ddraw/tests: Remove some error checking from ProcessVerticesTest().
[wine.git] / dlls / ddraw / tests / d3d.c
blob43d53af27e8c55dd7a1c7a427448a00917a02d76
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;
38 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest1 = NULL;
39 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest2 = NULL;
41 static IDirectDraw *DirectDraw1 = NULL;
42 static IDirectDrawSurface *Surface1 = NULL;
43 static IDirect3D *Direct3D1 = NULL;
44 static IDirect3DDevice *Direct3DDevice1 = NULL;
45 static IDirect3DExecuteBuffer *ExecuteBuffer = NULL;
46 static IDirect3DViewport *Viewport = NULL;
47 static IDirect3DLight *Light = NULL;
49 typedef struct {
50 int total;
51 int rgb;
52 int hal;
53 int tnlhal;
54 int unk;
55 } D3D7ETest;
57 typedef struct {
58 HRESULT desired_ret;
59 int total;
60 } D3D7ECancelTest;
62 #define MAX_ENUMERATION_COUNT 10
63 typedef struct
65 unsigned int count;
66 char *callback_description_ptrs[MAX_ENUMERATION_COUNT];
67 char callback_description_strings[MAX_ENUMERATION_COUNT][100];
68 char *callback_name_ptrs[MAX_ENUMERATION_COUNT];
69 char callback_name_strings[MAX_ENUMERATION_COUNT][100];
70 } D3D7ELifetimeTest;
72 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
74 struct vec3
76 float x, y, z;
79 struct vec4
81 float x, y, z, w;
84 static BOOL compare_float(float f, float g, unsigned int ulps)
86 int x = *(int *)&f;
87 int y = *(int *)&g;
89 if (x < 0)
90 x = INT_MIN - x;
91 if (y < 0)
92 y = INT_MIN - y;
94 if (abs(x - y) > ulps)
95 return FALSE;
97 return TRUE;
100 static BOOL compare_vec3(struct vec3 *vec, float x, float y, float z, unsigned int ulps)
102 return compare_float(vec->x, x, ulps)
103 && compare_float(vec->y, y, ulps)
104 && compare_float(vec->z, z, ulps);
107 static BOOL compare_vec4(struct vec4 *vec, float x, float y, float z, float w, unsigned int ulps)
109 return compare_float(vec->x, x, ulps)
110 && compare_float(vec->y, y, ulps)
111 && compare_float(vec->z, z, ulps)
112 && compare_float(vec->w, w, ulps);
115 static void init_function_pointers(void)
117 HMODULE hmod = GetModuleHandleA("ddraw.dll");
118 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
122 static ULONG getRefcount(IUnknown *iface)
124 IUnknown_AddRef(iface);
125 return IUnknown_Release(iface);
128 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
130 UINT *num = context;
131 (*num)++;
132 IDirectDrawSurface_Release(surface);
133 return DDENUMRET_OK;
136 static BOOL CreateDirect3D(void)
138 HRESULT rc;
139 DDSURFACEDESC2 ddsd;
140 UINT num;
142 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
143 &IID_IDirectDraw7, NULL);
144 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
145 if (!lpDD) {
146 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
147 return FALSE;
150 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
151 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
153 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
154 if (rc == E_NOINTERFACE) return FALSE;
155 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
157 memset(&ddsd, 0, sizeof(ddsd));
158 ddsd.dwSize = sizeof(ddsd);
159 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
160 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
161 ddsd.dwWidth = 256;
162 ddsd.dwHeight = 256;
163 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
164 if (FAILED(rc))
165 return FALSE;
167 num = 0;
168 IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, NULL, &num, SurfaceCounter);
169 ok(num == 1, "Has %d surfaces, expected 1\n", num);
171 memset(&ddsd, 0, sizeof(ddsd));
172 ddsd.dwSize = sizeof(ddsd);
173 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
174 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
175 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
176 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
177 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
178 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
179 ddsd.dwWidth = 256;
180 ddsd.dwHeight = 256;
181 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
182 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
183 if (FAILED(rc)) {
184 lpDDSdepth = NULL;
185 } else {
186 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
187 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
188 if (FAILED(rc))
189 return FALSE;
192 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
193 &lpD3DDevice);
194 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
195 if (!lpD3DDevice) {
196 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
197 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
198 &lpD3DDevice);
199 if (!lpD3DDevice) {
200 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
201 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
202 &lpD3DDevice);
203 if (!lpD3DDevice) {
204 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
205 return FALSE;
210 return TRUE;
213 static void ReleaseDirect3D(void)
215 if (lpD3DDevice != NULL)
217 IDirect3DDevice7_Release(lpD3DDevice);
218 lpD3DDevice = NULL;
221 if (lpDDSdepth != NULL)
223 IDirectDrawSurface_Release(lpDDSdepth);
224 lpDDSdepth = NULL;
227 if (lpDDS != NULL)
229 IDirectDrawSurface_Release(lpDDS);
230 lpDDS = NULL;
233 if (lpD3D != NULL)
235 IDirect3D7_Release(lpD3D);
236 lpD3D = NULL;
239 if (lpDD != NULL)
241 IDirectDraw_Release(lpDD);
242 lpDD = NULL;
246 static void LightTest(void)
248 HRESULT rc;
249 D3DLIGHT7 light;
250 D3DLIGHT7 defaultlight;
251 BOOL bEnabled = FALSE;
252 float one = 1.0f;
253 float zero= 0.0f;
254 D3DMATERIAL7 mat;
255 BOOL enabled;
256 unsigned int i;
257 D3DDEVICEDESC7 caps;
259 /* Set a few lights with funky indices. */
260 memset(&light, 0, sizeof(light));
261 light.dltType = D3DLIGHT_DIRECTIONAL;
262 U1(light.dcvDiffuse).r = 0.5f;
263 U2(light.dcvDiffuse).g = 0.6f;
264 U3(light.dcvDiffuse).b = 0.7f;
265 U2(light.dvDirection).y = 1.f;
267 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
268 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
269 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
270 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
271 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
272 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
275 /* Try to retrieve a light beyond the indices of the lights that have
276 been set. */
277 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
278 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
279 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
280 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
283 /* Try to retrieve one of the lights that have been set */
284 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
285 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
288 /* Enable a light that have been previously set. */
289 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
290 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
293 /* Enable some lights that have not been previously set, and verify that
294 they have been initialized with proper default values. */
295 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
296 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
297 U1(defaultlight.dcvDiffuse).r = 1.f;
298 U2(defaultlight.dcvDiffuse).g = 1.f;
299 U3(defaultlight.dcvDiffuse).b = 1.f;
300 U3(defaultlight.dvDirection).z = 1.f;
302 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
303 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
304 memset(&light, 0, sizeof(D3DLIGHT7));
305 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
306 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
307 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
308 "light data doesn't match expected default values\n" );
310 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
311 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
312 memset(&light, 0, sizeof(D3DLIGHT7));
313 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
314 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
315 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
316 "light data doesn't match expected default values\n" );
319 /* Disable one of the light that have been previously enabled. */
320 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
321 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
323 /* Try to retrieve the enable status of some lights */
324 /* Light 20 is supposed to be disabled */
325 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
326 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
327 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
329 /* Light 10 is supposed to be enabled */
330 bEnabled = FALSE;
331 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
332 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
333 ok(bEnabled, "GetLightEnable says the light is disabled\n");
335 /* Light 80 has not been set */
336 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
337 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
339 /* Light 23 has not been set */
340 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
341 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
343 /* Set some lights with invalid parameters */
344 memset(&light, 0, sizeof(D3DLIGHT7));
345 light.dltType = 0;
346 U1(light.dcvDiffuse).r = 1.f;
347 U2(light.dcvDiffuse).g = 1.f;
348 U3(light.dcvDiffuse).b = 1.f;
349 U3(light.dvDirection).z = 1.f;
350 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
351 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
353 memset(&light, 0, sizeof(D3DLIGHT7));
354 light.dltType = 12345;
355 U1(light.dcvDiffuse).r = 1.f;
356 U2(light.dcvDiffuse).g = 1.f;
357 U3(light.dcvDiffuse).b = 1.f;
358 U3(light.dvDirection).z = 1.f;
359 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
360 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
362 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
363 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
365 memset(&light, 0, sizeof(D3DLIGHT7));
366 light.dltType = D3DLIGHT_SPOT;
367 U1(light.dcvDiffuse).r = 1.f;
368 U2(light.dcvDiffuse).g = 1.f;
369 U3(light.dcvDiffuse).b = 1.f;
370 U3(light.dvDirection).z = 1.f;
372 light.dvAttenuation0 = -one / zero; /* -INFINITY */
373 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
374 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
376 light.dvAttenuation0 = -1.0;
377 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
378 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
380 light.dvAttenuation0 = 0.0;
381 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
382 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
384 light.dvAttenuation0 = 1.0;
385 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
386 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
388 light.dvAttenuation0 = one / zero; /* +INFINITY */
389 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
390 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
392 light.dvAttenuation0 = zero / zero; /* NaN */
393 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
394 ok(rc==D3D_OK ||
395 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
397 /* Directional light ignores attenuation */
398 light.dltType = D3DLIGHT_DIRECTIONAL;
399 light.dvAttenuation0 = -1.0;
400 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
401 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
403 memset(&mat, 0, sizeof(mat));
404 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
405 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
407 U4(mat).power = 129.0;
408 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
409 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
410 memset(&mat, 0, sizeof(mat));
411 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
412 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
413 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
415 U4(mat).power = -1.0;
416 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
417 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
418 memset(&mat, 0, sizeof(mat));
419 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
420 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
421 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
423 memset(&caps, 0, sizeof(caps));
424 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
425 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
427 if ( caps.dwMaxActiveLights == (DWORD) -1) {
428 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
429 skip("T&L not supported\n");
430 return;
433 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
434 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
435 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
436 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
437 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
438 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
441 /* TODO: Test the rendering results in this situation */
442 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
443 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
444 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
445 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
446 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
447 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
448 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
450 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
451 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
452 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
456 static void ProcessVerticesTest(void)
458 D3DVERTEXBUFFERDESC desc;
459 struct vec4 *out;
460 struct vec3 *out2;
461 struct vec3 *in;
462 D3DVIEWPORT7 vp;
463 HRESULT hr;
465 D3DMATRIX view = { 2.0, 0.0, 0.0, 0.0,
466 0.0, -1.0, 0.0, 0.0,
467 0.0, 0.0, 1.0, 0.0,
468 0.0, 0.0, 0.0, 3.0 };
470 D3DMATRIX world = { 0.0, 1.0, 0.0, 0.0,
471 1.0, 0.0, 0.0, 0.0,
472 0.0, 0.0, 0.0, 1.0,
473 0.0, 1.0, 1.0, 1.0 };
475 D3DMATRIX proj = { 1.0, 0.0, 0.0, 1.0,
476 0.0, 1.0, 1.0, 0.0,
477 0.0, 1.0, 1.0, 0.0,
478 1.0, 0.0, 0.0, 1.0 };
479 /* Create some vertex buffers */
481 memset(&desc, 0, sizeof(desc));
482 desc.dwSize = sizeof(desc);
483 desc.dwCaps = 0;
484 desc.dwFVF = D3DFVF_XYZ;
485 desc.dwNumVertices = 16;
486 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
487 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
489 memset(&desc, 0, sizeof(desc));
490 desc.dwSize = sizeof(desc);
491 desc.dwCaps = 0;
492 desc.dwFVF = D3DFVF_XYZRHW;
493 desc.dwNumVertices = 16;
494 /* Msdn says that the last parameter must be 0 - check that */
495 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest1, 4);
496 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
498 memset(&desc, 0, sizeof(desc));
499 desc.dwSize = sizeof(desc);
500 desc.dwCaps = 0;
501 desc.dwFVF = D3DFVF_XYZ;
502 desc.dwNumVertices = 16;
503 /* Msdn says that the last parameter must be 0 - check that */
504 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest2, 12345678);
505 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
507 hr = IDirect3DVertexBuffer7_Lock(lpVBufSrc, 0, (void **)&in, NULL);
508 ok(SUCCEEDED(hr), "Failed to lock source vertex buffer, hr %#x.\n", hr);
509 in[0].x = 0.0f;
510 in[0].y = 0.0f;
511 in[0].z = 0.0f;
512 in[1].x = 1.0f;
513 in[1].y = 1.0f;
514 in[1].z = 1.0f;
515 in[2].x = -1.0f;
516 in[2].y = -1.0f;
517 in[2].z = 0.5f;
518 in[3].x = 0.5f;
519 in[3].y = -0.5f;
520 in[3].z = 0.25f;
521 hr = IDirect3DVertexBuffer7_Unlock(lpVBufSrc);
522 ok(SUCCEEDED(hr), "Failed to unlock source vertex buffer, hr %#x.\n", hr);
524 memset(&vp, 0, sizeof(vp));
525 vp.dwX = 64;
526 vp.dwY = 64;
527 vp.dwWidth = 128;
528 vp.dwHeight = 128;
529 vp.dvMinZ = 0.0f;
530 vp.dvMaxZ = 1.0f;
531 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
532 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
534 hr = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
535 ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
536 hr = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest2, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
537 ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
539 hr = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **)&out, NULL);
540 ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
541 ok(compare_vec4(&out[0], +1.280e+2f, +1.280e+2f, +0.000e+0f, +1.000e+0f, 4096),
542 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
543 out[0].x, out[0].y, out[0].z, out[0].w);
544 ok(compare_vec4(&out[1], +1.920e+2f, +6.400e+1f, +1.000e+0f, +1.000e+0f, 4096),
545 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
546 out[1].x, out[1].y, out[1].z, out[1].w);
547 ok(compare_vec4(&out[2], +6.400e+1f, +1.920e+2f, +5.000e-1f, +1.000e+0f, 4096),
548 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
549 out[2].x, out[2].y, out[2].z, out[2].w);
550 ok(compare_vec4(&out[3], +1.600e+2f, +1.600e+2f, +2.500e-1f, +1.000e+0f, 4096),
551 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
552 out[3].x, out[3].y, out[3].z, out[3].w);
553 hr = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
554 ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
555 out = NULL;
557 hr = IDirect3DVertexBuffer7_Lock(lpVBufDest2, 0, (void **)&out2, NULL);
558 ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
559 /* Small thing without much practical meaning, but I stumbled upon it,
560 * so let's check for it: If the output vertex buffer has to RHW value,
561 * The RHW value of the last vertex is written into the next vertex. */
562 ok(compare_vec3(&out2[4], +1.000e+0f, +0.000e+0f, +0.000e+0f, 4096),
563 "Got unexpected vertex 4 {%.8e, %.8e, %.8e}.\n",
564 out2[4].x, out2[4].y, out2[4].z);
565 hr = IDirect3DVertexBuffer7_Unlock(lpVBufDest2);
566 ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
567 out = NULL;
569 /* Try a more complicated viewport, same vertices. */
570 memset(&vp, 0, sizeof(vp));
571 vp.dwX = 10;
572 vp.dwY = 5;
573 vp.dwWidth = 246;
574 vp.dwHeight = 130;
575 vp.dvMinZ = -2.0;
576 vp.dvMaxZ = 4.0;
577 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
578 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
580 /* Process again */
581 hr = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
582 ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
584 hr = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
585 ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
586 ok(compare_vec4(&out[0], +1.330e+2f, +7.000e+1f, -2.000e+0f, +1.000e+0f, 4096),
587 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
588 out[0].x, out[0].y, out[0].z, out[0].w);
589 ok(compare_vec4(&out[1], +2.560e+2f, +5.000e+0f, +4.000e+0f, +1.000e+0f, 4096),
590 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
591 out[1].x, out[1].y, out[1].z, out[1].w);
592 ok(compare_vec4(&out[2], +1.000e+1f, +1.350e+2f, +1.000e+0f, +1.000e+0f, 4096),
593 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
594 out[2].x, out[2].y, out[2].z, out[2].w);
595 ok(compare_vec4(&out[3], +1.945e+2f, +1.025e+2f, -5.000e-1f, +1.000e+0f, 4096),
596 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
597 out[3].x, out[3].y, out[3].z, out[3].w);
598 hr = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
599 ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
600 out = NULL;
602 /* Play with some matrices. */
603 hr = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
604 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
605 hr = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW, &view);
606 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
607 hr = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
608 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
610 hr = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
611 ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
613 hr = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
614 ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
615 ok(compare_vec4(&out[0], +2.560e+2f, +7.000e+1f, -2.000e+0f, +3.333e-1f, 4096),
616 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
617 out[0].x, out[0].y, out[0].z, out[0].w);
618 ok(compare_vec4(&out[1], +2.560e+2f, +7.813e+1f, -2.750e+0f, +1.250e-1f, 4096),
619 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
620 out[1].x, out[1].y, out[1].z, out[1].w);
621 ok(compare_vec4(&out[2], +2.560e+2f, +4.400e+1f, +4.000e-1f, +4.000e-1f, 4096),
622 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
623 out[2].x, out[2].y, out[2].z, out[2].w);
624 ok(compare_vec4(&out[3], +2.560e+2f, +8.182e+1f, -3.091e+0f, +3.636e-1f, 4096),
625 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
626 out[3].x, out[3].y, out[3].z, out[3].w);
627 hr = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
628 ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
629 out = NULL;
631 IDirect3DVertexBuffer7_Release(lpVBufSrc);
632 IDirect3DVertexBuffer7_Release(lpVBufDest1);
633 IDirect3DVertexBuffer7_Release(lpVBufDest2);
636 static void StateTest( void )
638 HRESULT rc;
640 /* The msdn says its undocumented, does it return an error too? */
641 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
642 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
643 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
644 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
648 static void SceneTest(void)
650 HRESULT hr;
652 /* Test an EndScene without BeginScene. Should return an error */
653 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
654 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
656 /* Test a normal BeginScene / EndScene pair, this should work */
657 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
658 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
659 if (SUCCEEDED(hr))
661 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
662 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
665 if (lpDDSdepth)
667 DDBLTFX fx;
668 memset(&fx, 0, sizeof(fx));
669 fx.dwSize = sizeof(fx);
671 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
672 ok(hr == D3D_OK, "Depthfill failed outside a BeginScene / EndScene pair, hr 0x%08x\n", hr);
674 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
675 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
676 if (SUCCEEDED(hr))
678 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
679 ok(hr == D3D_OK || broken(hr == E_FAIL),
680 "Depthfill failed in a BeginScene / EndScene pair, hr 0x%08x\n", hr);
681 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
682 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
685 else
687 skip("Depth stencil creation failed at startup, skipping depthfill test\n");
690 /* Test another EndScene without having begun a new scene. Should return an error */
691 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
692 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
694 /* Two nested BeginScene and EndScene calls */
695 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
696 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
697 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
698 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
699 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
700 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
701 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
702 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
704 /* TODO: Verify that blitting works in the same way as in d3d9 */
707 static void LimitTest(void)
709 IDirectDrawSurface7 *pTexture = NULL;
710 HRESULT hr;
711 int i;
712 DDSURFACEDESC2 ddsd;
714 memset(&ddsd, 0, sizeof(ddsd));
715 ddsd.dwSize = sizeof(ddsd);
716 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
717 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
718 ddsd.dwWidth = 16;
719 ddsd.dwHeight = 16;
720 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
721 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
722 if(!pTexture) return;
724 for(i = 0; i < 8; i++) {
725 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
726 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
727 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
728 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
729 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
730 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
733 IDirectDrawSurface7_Release(pTexture);
736 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
738 UINT ver = *((UINT *) ctx);
739 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
741 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
742 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
743 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
744 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
745 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
746 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
747 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
748 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
750 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
751 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
752 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
753 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
754 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
755 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
756 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
757 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
759 ok(hal->dcmColorModel == 0, "RGB Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
760 ok(hel->dcmColorModel == D3DCOLOR_RGB, "RGB Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
762 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
764 trace("HAL Device %d\n", ver);
765 ok(hal->dcmColorModel == D3DCOLOR_RGB, "HAL Device %u hal caps has colormodel %u\n", ver, hel->dcmColorModel);
766 ok(hel->dcmColorModel == 0, "HAL Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
768 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
770 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
771 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
772 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
773 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
774 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
775 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
776 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
777 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
779 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
780 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
781 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
782 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
783 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
784 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
785 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
786 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
788 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
790 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
791 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
792 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
793 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
794 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
795 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
796 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
797 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
799 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
800 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
801 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
802 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
803 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
804 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
805 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
806 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
808 ok(hal->dcmColorModel == 0, "Ramp Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
809 ok(hel->dcmColorModel == D3DCOLOR_MONO, "Ramp Device %u hel caps has colormodel %u\n",
810 ver, hel->dcmColorModel);
812 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
814 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
815 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
816 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
817 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
818 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
819 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
820 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
821 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
823 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
824 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
825 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
826 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
827 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
828 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
829 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
830 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
832 ok(hal->dcmColorModel == 0, "MMX Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
833 ok(hel->dcmColorModel == D3DCOLOR_RGB, "MMX Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
835 else
837 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
838 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
839 else trace("hal line does NOT have pow2 set\n");
840 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
841 else trace("hal tri does NOT have pow2 set\n");
842 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
843 else trace("hel line does NOT have pow2 set\n");
844 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
845 else trace("hel tri does NOT have pow2 set\n");
847 return DDENUMRET_OK;
850 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
852 D3D7ETest *d3d7et = Context;
853 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
854 d3d7et->rgb++;
855 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
856 d3d7et->hal++;
857 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
858 d3d7et->tnlhal++;
859 else
860 d3d7et->unk++;
862 d3d7et->total++;
864 return DDENUMRET_OK;
867 static HRESULT WINAPI enumDevicesCancelTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
869 D3D7ECancelTest *d3d7et = Context;
871 d3d7et->total++;
873 return d3d7et->desired_ret;
876 static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
878 D3D7ELifetimeTest *ctx = Context;
880 if (ctx->count == MAX_ENUMERATION_COUNT)
882 ok(0, "Enumerated too many devices for context in callback\n");
883 return DDENUMRET_CANCEL;
886 ctx->callback_description_ptrs[ctx->count] = DeviceDescription;
887 strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription);
888 ctx->callback_name_ptrs[ctx->count] = DeviceName;
889 strcpy(ctx->callback_name_strings[ctx->count], DeviceName);
891 ctx->count++;
892 return DDENUMRET_OK;
895 /* Check the deviceGUID of devices enumerated by
896 IDirect3D7_EnumDevices. */
897 static void D3D7EnumTest(void)
899 HRESULT hr;
900 D3D7ETest d3d7et;
901 D3D7ECancelTest d3d7_cancel_test;
903 hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
904 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
906 memset(&d3d7et, 0, sizeof(d3d7et));
907 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
908 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
910 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
911 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
913 /* We make two additional assumptions. */
914 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
916 if(d3d7et.tnlhal)
917 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
919 d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
920 d3d7_cancel_test.total = 0;
921 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
922 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
924 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
925 d3d7_cancel_test.total);
927 /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */
928 d3d7_cancel_test.desired_ret = E_INVALIDARG;
929 d3d7_cancel_test.total = 0;
930 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCancelTest7, &d3d7_cancel_test);
931 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
933 ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n",
934 d3d7_cancel_test.total);
937 static void D3D7EnumLifetimeTest(void)
939 D3D7ELifetimeTest ctx, ctx2;
940 HRESULT hr;
941 unsigned int i;
943 ctx.count = 0;
944 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx);
945 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
947 /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */
948 for (i = 0; i < ctx.count; i++)
950 ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]),
951 "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]);
952 ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]),
953 "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]);
956 ctx2.count = 0;
957 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
958 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
960 /* The enumeration strings and their order are identical across enumerations. */
961 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
962 if (ctx.count == ctx2.count)
964 for (i = 0; i < ctx.count; i++)
966 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
967 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
968 ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]),
969 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
970 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
971 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
972 ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]),
973 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
977 /* Try altering the contents of the enumeration strings. */
978 for (i = 0; i < ctx2.count; i++)
980 strcpy(ctx2.callback_description_ptrs[i], "Fake Description");
981 strcpy(ctx2.callback_name_ptrs[i], "Fake Device");
984 ctx2.count = 0;
985 hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesLifetimeTest7, &ctx2);
986 ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
988 /* The original contents of the enumeration strings are not restored. */
989 ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count);
990 if (ctx.count == ctx2.count)
992 for (i = 0; i < ctx.count; i++)
994 ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i],
995 "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]);
996 ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0,
997 "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]);
998 ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i],
999 "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]);
1000 ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0,
1001 "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]);
1006 static void CapsTest(void)
1008 IDirect3D3 *d3d3;
1009 IDirect3D3 *d3d2;
1010 IDirectDraw *dd1;
1011 HRESULT hr;
1012 UINT ver;
1014 hr = DirectDrawCreate(NULL, &dd1, NULL);
1015 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1016 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
1017 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1019 hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
1020 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
1022 ver = 3;
1023 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
1025 IDirect3D3_Release(d3d3);
1026 IDirectDraw_Release(dd1);
1028 hr = DirectDrawCreate(NULL, &dd1, NULL);
1029 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
1030 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
1031 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1033 hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
1034 ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
1036 ver = 2;
1037 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
1039 IDirect3D2_Release(d3d2);
1040 IDirectDraw_Release(dd1);
1043 struct v_in {
1044 float x, y, z;
1046 struct v_out {
1047 float x, y, z, rhw;
1050 static BOOL D3D1_createObjects(void)
1052 HRESULT hr;
1053 DDSURFACEDESC ddsd;
1054 D3DEXECUTEBUFFERDESC desc;
1055 D3DVIEWPORT vp_data;
1057 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
1058 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
1059 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
1060 if (!DirectDraw1) {
1061 return FALSE;
1064 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
1065 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
1067 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
1068 if (hr == E_NOINTERFACE) return FALSE;
1069 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
1070 if (!Direct3D1) {
1071 return FALSE;
1074 memset(&ddsd, 0, sizeof(ddsd));
1075 ddsd.dwSize = sizeof(ddsd);
1076 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1077 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
1078 ddsd.dwWidth = 256;
1079 ddsd.dwHeight = 256;
1080 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
1081 if (!Surface1) {
1082 skip("DDSCAPS_3DDEVICE surface not available\n");
1083 return FALSE;
1086 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
1087 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
1088 if(!Direct3DDevice1) {
1089 return FALSE;
1092 memset(&desc, 0, sizeof(desc));
1093 desc.dwSize = sizeof(desc);
1094 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
1095 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
1096 desc.dwBufferSize = 128;
1097 desc.lpData = NULL;
1098 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
1099 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
1100 if(!ExecuteBuffer) {
1101 return FALSE;
1104 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
1105 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
1106 if(!Viewport) {
1107 return FALSE;
1110 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
1111 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
1113 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1114 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1115 vp_data.dwSize = sizeof(vp_data);
1116 vp_data.dwX = 0;
1117 vp_data.dwY = 0;
1118 vp_data.dwWidth = 256;
1119 vp_data.dwHeight = 256;
1120 vp_data.dvScaleX = 1;
1121 vp_data.dvScaleY = 1;
1122 vp_data.dvMaxX = 256;
1123 vp_data.dvMaxY = 256;
1124 vp_data.dvMinZ = 0;
1125 vp_data.dvMaxZ = 1;
1126 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1127 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1129 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1130 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1131 if (!Light)
1132 return FALSE;
1134 return TRUE;
1137 static void D3D1_releaseObjects(void)
1139 if (Light) IDirect3DLight_Release(Light);
1140 if (Viewport) IDirect3DViewport_Release(Viewport);
1141 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1142 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1143 if (Surface1) IDirectDrawSurface_Release(Surface1);
1144 if (Direct3D1) IDirect3D_Release(Direct3D1);
1145 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1148 static void ViewportTest(void)
1150 HRESULT hr;
1151 LPDIRECT3DVIEWPORT2 Viewport2;
1152 IDirect3DViewport3 *Viewport3;
1153 D3DVIEWPORT vp1_data, ret_vp1_data;
1154 D3DVIEWPORT2 vp2_data, ret_vp2_data;
1155 float infinity;
1157 *(DWORD*)&infinity = 0x7f800000;
1159 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1160 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1162 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
1163 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1164 ok(Viewport2 == (IDirect3DViewport2 *)Viewport, "IDirect3DViewport2 iface diffrent from IDirect3DViewport\n");
1166 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport3, (void**) &Viewport3);
1167 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1168 ok(Viewport3 == (IDirect3DViewport3 *)Viewport, "IDirect3DViewport3 iface diffrent from IDirect3DViewport\n");
1169 IDirect3DViewport3_Release(Viewport3);
1171 vp1_data.dwSize = sizeof(vp1_data);
1172 vp1_data.dwX = 0;
1173 vp1_data.dwY = 1;
1174 vp1_data.dwWidth = 256;
1175 vp1_data.dwHeight = 257;
1176 vp1_data.dvMaxX = 0;
1177 vp1_data.dvMaxY = 0;
1178 vp1_data.dvScaleX = 0;
1179 vp1_data.dvScaleY = 0;
1180 vp1_data.dvMinZ = 0.25;
1181 vp1_data.dvMaxZ = 0.75;
1183 vp2_data.dwSize = sizeof(vp2_data);
1184 vp2_data.dwX = 2;
1185 vp2_data.dwY = 3;
1186 vp2_data.dwWidth = 258;
1187 vp2_data.dwHeight = 259;
1188 vp2_data.dvClipX = 0;
1189 vp2_data.dvClipY = 0;
1190 vp2_data.dvClipWidth = 0;
1191 vp2_data.dvClipHeight = 0;
1192 vp2_data.dvMinZ = 0.1;
1193 vp2_data.dvMaxZ = 0.9;
1195 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1196 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1198 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1199 ret_vp1_data.dwSize = sizeof(vp1_data);
1201 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1202 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1204 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1205 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1206 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1207 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1208 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1209 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1210 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1211 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1212 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1213 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1215 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1216 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1218 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1219 ret_vp2_data.dwSize = sizeof(vp2_data);
1221 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1222 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1224 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1225 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1226 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1227 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1228 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1229 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1230 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1231 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1232 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1233 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1234 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1235 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1237 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1238 ret_vp1_data.dwSize = sizeof(vp1_data);
1240 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1241 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1243 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1244 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1245 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1246 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1247 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1248 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1249 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1250 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1251 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1252 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1254 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1255 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1257 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1258 ret_vp2_data.dwSize = sizeof(vp2_data);
1260 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1261 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1263 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1264 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1265 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1266 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1267 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1268 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1269 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1270 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1271 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1272 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1273 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1274 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1276 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1277 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1279 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1280 ret_vp1_data.dwSize = sizeof(vp1_data);
1282 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1283 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1285 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1286 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1287 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1288 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1289 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1290 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1291 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1292 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1293 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1294 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1296 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1297 ret_vp2_data.dwSize = sizeof(vp2_data);
1299 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1300 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1302 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1303 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1304 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1305 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1306 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1307 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1308 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1309 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1310 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1311 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1312 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1313 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1315 IDirect3DViewport2_Release(Viewport2);
1317 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1318 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1321 #define SET_VP_DATA(vp_data) \
1322 vp_data.dwSize = sizeof(vp_data); \
1323 vp_data.dwX = 0; \
1324 vp_data.dwY = 0; \
1325 vp_data.dwWidth = 256; \
1326 vp_data.dwHeight = 256; \
1327 vp_data.dvMaxX = 256; \
1328 vp_data.dvMaxY = 256; \
1329 vp_data.dvScaleX = 5; \
1330 vp_data.dvScaleY = 5; \
1331 vp_data.dvMinZ = -25; \
1332 vp_data.dvMaxZ = 60;
1334 static void Direct3D1Test(void)
1336 HRESULT hr;
1337 D3DEXECUTEBUFFERDESC desc;
1338 D3DVIEWPORT vp_data;
1339 D3DINSTRUCTION *instr;
1340 D3DBRANCH *branch;
1341 IDirect3D *Direct3D_alt;
1342 IDirect3DLight *d3dlight;
1343 ULONG refcount;
1344 unsigned int idx = 0;
1345 static struct v_in testverts[] = {
1346 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1347 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1349 static struct v_in cliptest[] = {
1350 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1351 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1353 static struct v_in offscreentest[] = {
1354 {128.1, 0.0, 0.0},
1356 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1357 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1358 D3DTRANSFORMDATA transformdata;
1359 DWORD i = FALSE;
1361 /* Interface consistency check. */
1362 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1363 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1364 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1365 IDirect3D_Release(Direct3D_alt);
1367 memset(&desc, 0, sizeof(desc));
1368 desc.dwSize = sizeof(desc);
1369 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1370 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1372 memset(desc.lpData, 0, 128);
1373 instr = desc.lpData;
1374 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1375 instr[idx].bSize = sizeof(*branch);
1376 instr[idx].wCount = 1;
1377 idx++;
1378 branch = (D3DBRANCH *) &instr[idx];
1379 branch->dwMask = 0x0;
1380 branch->dwValue = 1;
1381 branch->bNegate = TRUE;
1382 branch->dwOffset = 0;
1383 idx += (sizeof(*branch) / sizeof(*instr));
1384 instr[idx].bOpcode = D3DOP_EXIT;
1385 instr[idx].bSize = 0;
1386 instr[idx].wCount = 0;
1387 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1388 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1390 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1391 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1393 memset(&desc, 0, sizeof(desc));
1394 desc.dwSize = sizeof(desc);
1396 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1397 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1399 memset(desc.lpData, 0, 128);
1400 instr = desc.lpData;
1401 idx = 0;
1402 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1403 instr[idx].bSize = sizeof(*branch);
1404 instr[idx].wCount = 1;
1405 idx++;
1406 branch = (D3DBRANCH *) &instr[idx];
1407 branch->dwMask = 0x0;
1408 branch->dwValue = 1;
1409 branch->bNegate = TRUE;
1410 branch->dwOffset = 64;
1411 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1412 instr[0].bOpcode = D3DOP_EXIT;
1413 instr[0].bSize = 0;
1414 instr[0].wCount = 0;
1415 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1416 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1418 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1419 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1421 /* Test rendering 0 triangles */
1422 memset(&desc, 0, sizeof(desc));
1423 desc.dwSize = sizeof(desc);
1425 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1426 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1428 memset(desc.lpData, 0, 128);
1429 instr = desc.lpData;
1431 instr->bOpcode = D3DOP_TRIANGLE;
1432 instr->bSize = sizeof(D3DOP_TRIANGLE);
1433 instr->wCount = 0;
1434 instr++;
1435 instr->bOpcode = D3DOP_EXIT;
1436 instr->bSize = 0;
1437 instr->wCount = 0;
1438 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1439 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1441 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1442 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1444 memset(&transformdata, 0, sizeof(transformdata));
1445 transformdata.dwSize = sizeof(transformdata);
1446 transformdata.lpIn = testverts;
1447 transformdata.dwInSize = sizeof(testverts[0]);
1448 transformdata.lpOut = out;
1449 transformdata.dwOutSize = sizeof(out[0]);
1451 transformdata.lpHOut = NULL;
1452 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1453 &transformdata, D3DTRANSFORM_UNCLIPPED,
1454 &i);
1455 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1457 transformdata.lpHOut = outH;
1458 memset(outH, 0xcc, sizeof(outH));
1459 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1460 &transformdata, D3DTRANSFORM_UNCLIPPED,
1461 &i);
1462 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1463 ok(i == 0, "Offscreen is %d\n", i);
1465 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1466 static const struct v_out cmp[] = {
1467 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1468 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1471 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1472 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1473 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1474 out[i].x, out[i].y, out[i].z, out[i].rhw,
1475 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1477 for(i = 0; i < sizeof(outH); i++) {
1478 if(((unsigned char *) outH)[i] != 0xcc) {
1479 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1480 break;
1484 SET_VP_DATA(vp_data);
1485 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1486 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1487 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1488 &transformdata, D3DTRANSFORM_UNCLIPPED,
1489 &i);
1490 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1491 ok(i == 0, "Offscreen is %d\n", i);
1493 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1494 static const struct v_out cmp[] = {
1495 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1496 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1498 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1499 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1500 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1501 out[i].x, out[i].y, out[i].z, out[i].rhw,
1502 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1505 SET_VP_DATA(vp_data);
1506 vp_data.dwX = 10;
1507 vp_data.dwY = 20;
1508 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1509 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1510 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1511 &transformdata, D3DTRANSFORM_UNCLIPPED,
1512 &i);
1513 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1514 ok(i == 0, "Offscreen is %d\n", i);
1515 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1516 static const struct v_out cmp[] = {
1517 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1518 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1520 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1521 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1522 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1523 out[i].x, out[i].y, out[i].z, out[i].rhw,
1524 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1527 memset(out, 0xcc, sizeof(out));
1528 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1529 &transformdata, D3DTRANSFORM_CLIPPED,
1530 &i);
1531 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1532 ok(i == 0, "Offscreen is %d\n", i);
1533 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1534 static const D3DHVERTEX cmpH[] = {
1535 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1536 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1537 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1539 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1540 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1541 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1542 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1543 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1545 /* No scheme has been found behind those return values. It seems to be
1546 * whatever data windows has when throwing the vertex away. Modify the
1547 * input test vertices to test this more. Depending on the input data
1548 * it can happen that the z coord gets written into y, or similar things
1550 if(0)
1552 static const struct v_out cmp[] = {
1553 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1554 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1556 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1557 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1558 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1559 out[i].x, out[i].y, out[i].z, out[i].rhw,
1560 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1563 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1564 ok(((DWORD *) out)[i] != 0xcccccccc,
1565 "Regular output DWORD %d remained untouched\n", i);
1568 transformdata.lpIn = cliptest;
1569 transformdata.dwInSize = sizeof(cliptest[0]);
1570 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1571 &transformdata, D3DTRANSFORM_CLIPPED,
1572 &i);
1573 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1574 ok(i == 0, "Offscreen is %d\n", i);
1575 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1576 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1580 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1581 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1583 ok(Flags[i] == outH[i].dwFlags,
1584 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1585 outH[i].dwFlags, Flags[i]);
1588 SET_VP_DATA(vp_data);
1589 vp_data.dwWidth = 10;
1590 vp_data.dwHeight = 1000;
1591 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1592 i = 10;
1593 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1594 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1595 &transformdata, D3DTRANSFORM_CLIPPED,
1596 &i);
1597 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1598 ok(i == 0, "Offscreen is %d\n", i);
1599 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1600 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1602 D3DCLIP_RIGHT,
1603 D3DCLIP_LEFT,
1604 D3DCLIP_RIGHT | D3DCLIP_BACK,
1605 D3DCLIP_LEFT | D3DCLIP_FRONT,
1607 ok(Flags[i] == outH[i].dwFlags,
1608 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1609 outH[i].dwFlags, Flags[i]);
1612 SET_VP_DATA(vp_data);
1613 vp_data.dwWidth = 256;
1614 vp_data.dwHeight = 256;
1615 vp_data.dvScaleX = 1;
1616 vp_data.dvScaleY = 1;
1617 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1618 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1619 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1620 &transformdata, D3DTRANSFORM_CLIPPED,
1621 &i);
1622 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1623 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1624 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1625 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1629 D3DCLIP_BACK,
1630 D3DCLIP_FRONT,
1632 ok(Flags[i] == outH[i].dwFlags,
1633 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1634 outH[i].dwFlags, Flags[i]);
1637 /* Finally try to figure out how the DWORD dwOffscreen works.
1638 * Apparently no vertex is offscreen with clipping off,
1639 * and with clipping on the offscreen flag is set if only one vertex
1640 * is transformed, and this vertex is offscreen.
1642 SET_VP_DATA(vp_data);
1643 vp_data.dwWidth = 5;
1644 vp_data.dwHeight = 5;
1645 vp_data.dvScaleX = 10000;
1646 vp_data.dvScaleY = 10000;
1647 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1648 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1649 transformdata.lpIn = cliptest;
1650 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1651 &transformdata, D3DTRANSFORM_UNCLIPPED,
1652 &i);
1653 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1654 ok(i == 0, "Offscreen is %d\n", i);
1655 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1656 &transformdata, D3DTRANSFORM_CLIPPED,
1657 &i);
1658 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1659 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1660 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1661 &transformdata, D3DTRANSFORM_CLIPPED,
1662 &i);
1663 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1664 ok(i == 0, "Offscreen is %d\n", i);
1665 transformdata.lpIn = cliptest + 1;
1666 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1667 &transformdata, D3DTRANSFORM_CLIPPED,
1668 &i);
1669 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1670 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1672 transformdata.lpIn = offscreentest;
1673 transformdata.dwInSize = sizeof(offscreentest[0]);
1674 SET_VP_DATA(vp_data);
1675 vp_data.dwWidth = 257;
1676 vp_data.dwHeight = 257;
1677 vp_data.dvScaleX = 1;
1678 vp_data.dvScaleY = 1;
1679 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1680 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1681 i = 12345;
1682 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1683 &transformdata, D3DTRANSFORM_CLIPPED,
1684 &i);
1685 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1686 ok(i == 0, "Offscreen is %d\n", i);
1687 vp_data.dwWidth = 256;
1688 vp_data.dwHeight = 256;
1689 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1690 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1691 i = 12345;
1692 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1693 &transformdata, D3DTRANSFORM_CLIPPED,
1694 &i);
1695 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1696 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1698 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1699 &transformdata, 0,
1700 &i);
1701 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1703 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1704 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1706 hr = IDirect3DViewport_AddLight(Viewport, Light);
1707 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1708 refcount = getRefcount((IUnknown*) Light);
1709 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1711 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1712 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1713 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1714 refcount = getRefcount((IUnknown*) Light);
1715 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1717 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1718 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1719 refcount = getRefcount((IUnknown*) Light);
1720 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1722 IDirect3DLight_Release(Light);
1725 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1727 int i;
1729 for (i = 0; i < 256; i++) {
1730 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1731 table1[i].peBlue != table2[i].peBlue) return FALSE;
1734 return TRUE;
1737 /* test palette handling in IDirect3DTexture_Load */
1738 static void TextureLoadTest(void)
1740 IDirectDrawSurface *TexSurface = NULL;
1741 IDirect3DTexture *Texture = NULL;
1742 IDirectDrawSurface *TexSurface2 = NULL;
1743 IDirect3DTexture *Texture2 = NULL;
1744 IDirectDrawPalette *palette = NULL;
1745 IDirectDrawPalette *palette2 = NULL;
1746 IDirectDrawPalette *palette_tmp = NULL;
1747 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1748 HRESULT hr;
1749 DDSURFACEDESC ddsd;
1750 int i;
1752 memset (&ddsd, 0, sizeof (ddsd));
1753 ddsd.dwSize = sizeof (ddsd);
1754 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1755 ddsd.dwHeight = 128;
1756 ddsd.dwWidth = 128;
1757 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1758 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1759 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1760 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1762 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1763 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1764 if (FAILED(hr)) {
1765 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1766 goto cleanup;
1769 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1770 (void *)&Texture);
1771 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1772 if (FAILED(hr)) {
1773 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1774 goto cleanup;
1777 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1778 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1779 if (FAILED(hr)) {
1780 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1781 goto cleanup;
1784 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1785 (void *)&Texture2);
1786 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1787 if (FAILED(hr)) {
1788 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1789 goto cleanup;
1792 /* test load of Texture to Texture */
1793 hr = IDirect3DTexture_Load(Texture, Texture);
1794 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1796 /* test Load when both textures have no palette */
1797 hr = IDirect3DTexture_Load(Texture2, Texture);
1798 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1800 for (i = 0; i < 256; i++) {
1801 table1[i].peRed = i;
1802 table1[i].peGreen = i;
1803 table1[i].peBlue = i;
1804 table1[i].peFlags = 0;
1807 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1808 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1809 if (FAILED(hr)) {
1810 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1811 goto cleanup;
1814 /* test Load when source texture has palette and destination has no palette */
1815 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1816 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1817 hr = IDirect3DTexture_Load(Texture2, Texture);
1818 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1820 for (i = 0; i < 256; i++) {
1821 table2[i].peRed = 255 - i;
1822 table2[i].peGreen = 255 - i;
1823 table2[i].peBlue = 255 - i;
1824 table2[i].peFlags = 0;
1827 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1828 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1829 if (FAILED(hr)) {
1830 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1831 goto cleanup;
1834 /* test Load when source has no palette and destination has a palette */
1835 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1836 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1837 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1838 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1839 hr = IDirect3DTexture_Load(Texture2, Texture);
1840 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1841 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1842 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1843 if (!palette_tmp) {
1844 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1845 goto cleanup;
1846 } else {
1847 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1848 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1849 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1850 IDirectDrawPalette_Release(palette_tmp);
1853 /* test Load when both textures have palettes */
1854 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1855 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1856 hr = IDirect3DTexture_Load(Texture2, Texture);
1857 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1858 hr = IDirect3DTexture_Load(Texture2, Texture);
1859 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1860 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1861 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1862 if (!palette_tmp) {
1863 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1864 goto cleanup;
1865 } else {
1866 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1867 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1868 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1869 IDirectDrawPalette_Release(palette_tmp);
1872 cleanup:
1874 if (palette) IDirectDrawPalette_Release(palette);
1875 if (palette2) IDirectDrawPalette_Release(palette2);
1876 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1877 if (Texture) IDirect3DTexture_Release(Texture);
1878 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1879 if (Texture2) IDirect3DTexture_Release(Texture2);
1882 static void VertexBufferDescTest(void)
1884 HRESULT rc;
1885 D3DVERTEXBUFFERDESC desc;
1886 union mem_t
1888 D3DVERTEXBUFFERDESC desc2;
1889 unsigned char buffer[512];
1890 } mem;
1892 memset(&desc, 0, sizeof(desc));
1893 desc.dwSize = sizeof(desc);
1894 desc.dwCaps = 0;
1895 desc.dwFVF = D3DFVF_XYZ;
1896 desc.dwNumVertices = 1;
1897 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1898 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1899 if (!lpVBufSrc)
1901 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1902 goto out;
1905 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1906 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1907 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1908 if(rc != D3D_OK)
1909 skip("GetVertexBuffer Failed!\n");
1910 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1911 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1912 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1913 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1914 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1916 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1917 mem.desc2.dwSize = 0;
1918 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1919 if(rc != D3D_OK)
1920 skip("GetVertexBuffer Failed!\n");
1921 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1922 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1923 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1924 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1925 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1927 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1928 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1929 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1930 if(rc != D3D_OK)
1931 skip("GetVertexBuffer Failed!\n");
1932 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1933 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1934 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1935 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1936 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1938 out:
1939 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1942 static void D3D7_OldRenderStateTest(void)
1944 HRESULT hr;
1945 DWORD val;
1947 /* Test reaction to some deprecated states in D3D7. */
1948 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1949 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1950 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1951 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1952 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1953 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1954 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1955 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1958 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1959 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1961 static void DeviceLoadTest(void)
1963 DDSURFACEDESC2 ddsd;
1964 IDirectDrawSurface7 *texture_levels[2][8];
1965 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1966 DWORD flags;
1967 HRESULT hr;
1968 DDBLTFX ddbltfx;
1969 RECT loadrect;
1970 POINT loadpoint;
1971 int i, i1, i2;
1972 unsigned diff_count = 0, diff_count2 = 0;
1973 unsigned x, y;
1974 BOOL load_mip_subset_broken = FALSE;
1975 IDirectDrawPalette *palettes[5];
1976 PALETTEENTRY table1[256];
1977 DDCOLORKEY ddckey;
1978 D3DDEVICEDESC7 d3dcaps;
1980 /* Test loading of texture subrectangle with a mipmap surface. */
1981 memset(texture_levels, 0, sizeof(texture_levels));
1982 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1983 memset(palettes, 0, sizeof(palettes));
1985 for (i = 0; i < 2; i++)
1987 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1988 ddsd.dwSize = sizeof(ddsd);
1989 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1990 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1991 ddsd.dwWidth = 128;
1992 ddsd.dwHeight = 128;
1993 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1994 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1995 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1996 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1997 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1998 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1999 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2000 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2001 if (FAILED(hr)) goto out;
2003 /* Check the number of created mipmaps */
2004 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2005 ddsd.dwSize = sizeof(ddsd);
2006 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2007 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2008 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2009 if (U2(ddsd).dwMipMapCount != 8) goto out;
2011 for (i1 = 1; i1 < 8; i1++)
2013 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2014 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2015 if (FAILED(hr)) goto out;
2019 for (i1 = 0; i1 < 8; i1++)
2021 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2022 ddsd.dwSize = sizeof(ddsd);
2023 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2024 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2025 if (FAILED(hr)) goto out;
2027 for (y = 0 ; y < ddsd.dwHeight; y++)
2029 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2031 for (x = 0; x < ddsd.dwWidth; x++)
2033 /* x stored in green component, y in blue. */
2034 DWORD color = 0xff0000 | (x << 8) | y;
2035 *textureRow++ = color;
2039 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2040 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2043 for (i1 = 0; i1 < 8; i1++)
2045 memset(&ddbltfx, 0, sizeof(ddbltfx));
2046 ddbltfx.dwSize = sizeof(ddbltfx);
2047 U5(ddbltfx).dwFillColor = 0;
2048 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2049 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2052 /* First test some broken coordinates. */
2053 loadpoint.x = loadpoint.y = 0;
2054 loadrect.left = 0;
2055 loadrect.top = 0;
2056 loadrect.right = 0;
2057 loadrect.bottom = 0;
2058 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2059 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2061 loadpoint.x = loadpoint.y = 50;
2062 loadrect.left = 0;
2063 loadrect.top = 0;
2064 loadrect.right = 100;
2065 loadrect.bottom = 100;
2066 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2067 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2069 /* Test actual loading. */
2070 loadpoint.x = loadpoint.y = 31;
2071 loadrect.left = 30;
2072 loadrect.top = 20;
2073 loadrect.right = 93;
2074 loadrect.bottom = 52;
2076 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2077 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2079 for (i1 = 0; i1 < 8; i1++)
2081 diff_count = 0;
2082 diff_count2 = 0;
2084 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2085 ddsd.dwSize = sizeof(ddsd);
2086 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2087 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2088 if (FAILED(hr)) goto out;
2090 for (y = 0 ; y < ddsd.dwHeight; y++)
2092 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2094 for (x = 0; x < ddsd.dwWidth; x++)
2096 DWORD color = *textureRow++;
2098 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2099 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2101 if (color & 0xffffff) diff_count++;
2103 else
2105 DWORD r = (color & 0xff0000) >> 16;
2106 DWORD g = (color & 0xff00) >> 8;
2107 DWORD b = (color & 0xff);
2109 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
2112 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2113 technically be correct as it's not precisely defined by docs. */
2114 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2115 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2117 if (color & 0xffffff) diff_count2++;
2119 else
2121 DWORD r = (color & 0xff0000) >> 16;
2122 DWORD g = (color & 0xff00) >> 8;
2123 DWORD b = (color & 0xff);
2125 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2126 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2131 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2132 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2134 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2135 MIN(diff_count, diff_count2), i1);
2137 loadpoint.x /= 2;
2138 loadpoint.y /= 2;
2139 loadrect.top /= 2;
2140 loadrect.left /= 2;
2141 loadrect.right = (loadrect.right + 1) / 2;
2142 loadrect.bottom = (loadrect.bottom + 1) / 2;
2145 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2146 * qemu Win98 / directx7 / RGB software rasterizer):
2147 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2148 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2151 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2152 for (i = 0; i < 2; i++)
2154 for (i1 = 7; i1 >= 0; i1--)
2156 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2159 memset(texture_levels, 0, sizeof(texture_levels));
2161 /* Test texture size mismatch. */
2162 for (i = 0; i < 2; i++)
2164 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2165 ddsd.dwSize = sizeof(ddsd);
2166 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2167 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2168 ddsd.dwWidth = i ? 256 : 128;
2169 ddsd.dwHeight = 128;
2170 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2171 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2172 if (FAILED(hr)) goto out;
2175 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2176 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2178 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2179 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2181 IDirectDrawSurface7_Release(texture_levels[0][0]);
2182 IDirectDrawSurface7_Release(texture_levels[1][0]);
2183 memset(texture_levels, 0, sizeof(texture_levels));
2185 memset(&d3dcaps, 0, sizeof(d3dcaps));
2186 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2187 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2189 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2191 skip("No cubemap support\n");
2193 else
2195 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2196 for (i = 0; i < 2; i++)
2198 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2199 ddsd.dwSize = sizeof(ddsd);
2200 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2201 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2202 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2203 ddsd.dwWidth = 128;
2204 ddsd.dwHeight = 128;
2205 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2206 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2207 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2208 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2209 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2210 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2211 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2212 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2213 if (FAILED(hr)) goto out;
2215 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2216 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2218 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2219 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2220 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2221 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2222 if (FAILED(hr)) goto out;
2225 for (i1 = 0; i1 < 6; i1++)
2227 /* Check the number of created mipmaps */
2228 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2229 ddsd.dwSize = sizeof(ddsd);
2230 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2231 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2232 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2233 if (U2(ddsd).dwMipMapCount != 8) goto out;
2235 for (i2 = 1; i2 < 8; i2++)
2237 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2238 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2239 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2240 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2241 if (FAILED(hr)) goto out;
2246 for (i = 0; i < 6; i++)
2247 for (i1 = 0; i1 < 8; i1++)
2249 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2250 ddsd.dwSize = sizeof(ddsd);
2251 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2252 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2253 if (FAILED(hr)) goto out;
2255 for (y = 0 ; y < ddsd.dwHeight; y++)
2257 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2259 for (x = 0; x < ddsd.dwWidth; x++)
2261 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2262 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2263 *textureRow++ = color;
2267 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2268 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2271 for (i = 0; i < 6; i++)
2272 for (i1 = 0; i1 < 8; i1++)
2274 memset(&ddbltfx, 0, sizeof(ddbltfx));
2275 ddbltfx.dwSize = sizeof(ddbltfx);
2276 U5(ddbltfx).dwFillColor = 0;
2277 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2278 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2281 loadpoint.x = loadpoint.y = 10;
2282 loadrect.left = 30;
2283 loadrect.top = 20;
2284 loadrect.right = 93;
2285 loadrect.bottom = 52;
2287 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2288 DDSCAPS2_CUBEMAP_ALLFACES);
2289 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2291 for (i = 0; i < 6; i++)
2293 loadpoint.x = loadpoint.y = 10;
2294 loadrect.left = 30;
2295 loadrect.top = 20;
2296 loadrect.right = 93;
2297 loadrect.bottom = 52;
2299 for (i1 = 0; i1 < 8; i1++)
2301 diff_count = 0;
2302 diff_count2 = 0;
2304 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2305 ddsd.dwSize = sizeof(ddsd);
2306 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2307 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2308 if (FAILED(hr)) goto out;
2310 for (y = 0 ; y < ddsd.dwHeight; y++)
2312 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2314 for (x = 0; x < ddsd.dwWidth; x++)
2316 DWORD color = *textureRow++;
2318 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2319 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2321 if (color & 0xffffff) diff_count++;
2323 else
2325 DWORD r = (color & 0xff0000) >> 16;
2326 DWORD g = (color & 0xff00) >> 8;
2327 DWORD b = (color & 0xff);
2329 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2330 b != y + loadrect.top - loadpoint.y) diff_count++;
2333 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2334 technically be correct as it's not precisely defined by docs. */
2335 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2336 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2338 if (color & 0xffffff) diff_count2++;
2340 else
2342 DWORD r = (color & 0xff0000) >> 16;
2343 DWORD g = (color & 0xff00) >> 8;
2344 DWORD b = (color & 0xff);
2346 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2347 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2352 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2353 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2355 ok(diff_count == 0 || diff_count2 == 0,
2356 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2357 MIN(diff_count, diff_count2), i, i1);
2359 loadpoint.x /= 2;
2360 loadpoint.y /= 2;
2361 loadrect.top /= 2;
2362 loadrect.left /= 2;
2363 loadrect.right = (loadrect.right + 1) / 2;
2364 loadrect.bottom = (loadrect.bottom + 1) / 2;
2368 for (i = 0; i < 2; i++)
2369 for (i1 = 5; i1 >= 0; i1--)
2370 for (i2 = 7; i2 >= 0; i2--)
2372 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2374 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2376 /* Test cubemap loading from regular texture. */
2377 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2378 ddsd.dwSize = sizeof(ddsd);
2379 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2380 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2381 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2382 ddsd.dwWidth = 128;
2383 ddsd.dwHeight = 128;
2384 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2385 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2386 if (FAILED(hr)) goto out;
2388 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2389 ddsd.dwSize = sizeof(ddsd);
2390 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2391 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2392 ddsd.dwWidth = 128;
2393 ddsd.dwHeight = 128;
2394 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2395 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2396 if (FAILED(hr)) goto out;
2398 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2399 DDSCAPS2_CUBEMAP_ALLFACES);
2400 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2402 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2403 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2404 IDirectDrawSurface7_Release(texture_levels[0][0]);
2405 memset(texture_levels, 0, sizeof(texture_levels));
2407 /* Partial cube maps(e.g. created with an explicitly set DDSCAPS2_CUBEMAP_POSITIVEX flag)
2408 * BSOD some Windows machines when an app tries to create them(Radeon X1600, Windows XP,
2409 * Catalyst 10.2 driver, 6.14.10.6925)
2413 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2414 for (i = 0; i < 2; i++)
2416 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2417 ddsd.dwSize = sizeof(ddsd);
2418 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2419 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2420 ddsd.dwWidth = 128;
2421 ddsd.dwHeight = 128;
2422 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2423 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2424 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2425 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2426 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2427 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2428 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2429 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2430 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2431 if (FAILED(hr)) goto out;
2433 /* Check the number of created mipmaps */
2434 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2435 ddsd.dwSize = sizeof(ddsd);
2436 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2437 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2438 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2439 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2441 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2443 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2444 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2445 if (FAILED(hr)) goto out;
2449 for (i1 = 0; i1 < 8; i1++)
2451 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2452 ddsd.dwSize = sizeof(ddsd);
2453 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2454 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2455 if (FAILED(hr)) goto out;
2457 for (y = 0 ; y < ddsd.dwHeight; y++)
2459 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2461 for (x = 0; x < ddsd.dwWidth; x++)
2463 /* x stored in green component, y in blue. */
2464 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2465 *textureRow++ = color;
2469 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2470 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2473 for (i1 = 0; i1 < 4; i1++)
2475 memset(&ddbltfx, 0, sizeof(ddbltfx));
2476 ddbltfx.dwSize = sizeof(ddbltfx);
2477 U5(ddbltfx).dwFillColor = 0;
2478 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2479 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2482 loadpoint.x = loadpoint.y = 31;
2483 loadrect.left = 30;
2484 loadrect.top = 20;
2485 loadrect.right = 93;
2486 loadrect.bottom = 52;
2488 /* Destination mip levels are a subset of source mip levels. */
2489 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2490 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2492 for (i1 = 0; i1 < 4; i1++)
2494 diff_count = 0;
2495 diff_count2 = 0;
2497 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2498 ddsd.dwSize = sizeof(ddsd);
2499 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2500 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2501 if (FAILED(hr)) goto out;
2503 for (y = 0 ; y < ddsd.dwHeight; y++)
2505 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2507 for (x = 0; x < ddsd.dwWidth; x++)
2509 DWORD color = *textureRow++;
2511 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2512 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2514 if (color & 0xffffff) diff_count++;
2516 else
2518 DWORD r = (color & 0xff0000) >> 16;
2519 DWORD g = (color & 0xff00) >> 8;
2520 DWORD b = (color & 0xff);
2522 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2523 b != y + loadrect.top - loadpoint.y) diff_count++;
2526 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2527 technically be correct as it's not precisely defined by docs. */
2528 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2529 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2531 if (color & 0xffffff) diff_count2++;
2533 else
2535 DWORD r = (color & 0xff0000) >> 16;
2536 DWORD g = (color & 0xff00) >> 8;
2537 DWORD b = (color & 0xff);
2539 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2540 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2545 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2546 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2548 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2549 MIN(diff_count, diff_count2), i1);
2551 loadpoint.x /= 2;
2552 loadpoint.y /= 2;
2553 loadrect.top /= 2;
2554 loadrect.left /= 2;
2555 loadrect.right = (loadrect.right + 1) / 2;
2556 loadrect.bottom = (loadrect.bottom + 1) / 2;
2559 /* Destination mip levels are a superset of source mip levels (should fail). */
2560 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2561 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2563 for (i = 0; i < 2; i++)
2565 for (i1 = 7; i1 >= 0; i1--)
2567 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2570 memset(texture_levels, 0, sizeof(texture_levels));
2572 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2573 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2574 ddsd.dwSize = sizeof(ddsd);
2575 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2576 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2577 ddsd.dwWidth = 128;
2578 ddsd.dwHeight = 128;
2579 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2580 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2581 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2582 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2583 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2584 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2585 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2586 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2587 if (FAILED(hr)) goto out;
2589 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2590 ddsd.dwSize = sizeof(ddsd);
2591 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2592 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2593 ddsd.dwWidth = 32;
2594 ddsd.dwHeight = 32;
2595 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2596 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2597 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2598 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2599 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2600 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2601 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2602 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2603 if (FAILED(hr)) goto out;
2605 for (i1 = 1; i1 < 8; i1++)
2607 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2608 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2609 if (FAILED(hr)) goto out;
2612 for (i1 = 0; i1 < 8; i1++)
2614 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2615 ddsd.dwSize = sizeof(ddsd);
2616 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2617 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2618 if (FAILED(hr)) goto out;
2620 for (y = 0 ; y < ddsd.dwHeight; y++)
2622 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2624 for (x = 0; x < ddsd.dwWidth; x++)
2626 /* x stored in green component, y in blue. */
2627 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2628 *textureRow++ = color;
2632 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2633 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2636 memset(&ddbltfx, 0, sizeof(ddbltfx));
2637 ddbltfx.dwSize = sizeof(ddbltfx);
2638 U5(ddbltfx).dwFillColor = 0;
2639 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2640 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2642 loadpoint.x = loadpoint.y = 32;
2643 loadrect.left = 32;
2644 loadrect.top = 32;
2645 loadrect.right = 96;
2646 loadrect.bottom = 96;
2648 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2649 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2651 loadpoint.x /= 4;
2652 loadpoint.y /= 4;
2653 loadrect.top /= 4;
2654 loadrect.left /= 4;
2655 loadrect.right = (loadrect.right + 3) / 4;
2656 loadrect.bottom = (loadrect.bottom + 3) / 4;
2658 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2659 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2660 * copied subrectangles divided more than needed, without apparent logic. But it works
2661 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2662 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2663 * The following code attempts to detect broken results, actual tests will then be skipped
2665 load_mip_subset_broken = TRUE;
2666 diff_count = 0;
2668 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2669 ddsd.dwSize = sizeof(ddsd);
2670 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2671 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2672 if (FAILED(hr)) goto out;
2674 for (y = 0 ; y < ddsd.dwHeight; y++)
2676 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2678 for (x = 0; x < ddsd.dwWidth; x++)
2680 DWORD color = *textureRow++;
2682 if (x < 2 || x >= 2 + 4 ||
2683 y < 2 || y >= 2 + 4)
2685 if (color & 0xffffff) diff_count++;
2687 else
2689 DWORD r = (color & 0xff0000) >> 16;
2691 if ((r & (0xf0)) != 0xf0) diff_count++;
2696 if (diff_count) load_mip_subset_broken = FALSE;
2698 if (load_mip_subset_broken) {
2699 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2700 } else {
2701 diff_count = 0;
2703 for (y = 0 ; y < ddsd.dwHeight; y++)
2705 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2707 for (x = 0; x < ddsd.dwWidth; x++)
2709 DWORD color = *textureRow++;
2711 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2712 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2714 if (color & 0xffffff) diff_count++;
2716 else
2718 DWORD r = (color & 0xff0000) >> 16;
2719 DWORD g = (color & 0xff00) >> 8;
2720 DWORD b = (color & 0xff);
2722 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2723 b != y + loadrect.top - loadpoint.y) diff_count++;
2729 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2730 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2732 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2734 for (i = 0; i < 2; i++)
2736 for (i1 = 7; i1 >= 0; i1--)
2738 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2741 memset(texture_levels, 0, sizeof(texture_levels));
2743 if (!load_mip_subset_broken)
2745 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2746 * surface (than first source mip level)
2748 for (i = 0; i < 2; i++)
2750 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2751 ddsd.dwSize = sizeof(ddsd);
2752 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2753 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2754 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2755 ddsd.dwWidth = i ? 32 : 128;
2756 ddsd.dwHeight = i ? 32 : 128;
2757 if (i) U2(ddsd).dwMipMapCount = 4;
2758 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2759 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2760 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2761 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2762 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2763 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2764 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2765 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2766 if (FAILED(hr)) goto out;
2768 /* Check the number of created mipmaps */
2769 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2770 ddsd.dwSize = sizeof(ddsd);
2771 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2772 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2773 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2774 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2776 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2778 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2779 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2780 if (FAILED(hr)) goto out;
2784 for (i1 = 0; i1 < 8; i1++)
2786 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2787 ddsd.dwSize = sizeof(ddsd);
2788 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2789 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2790 if (FAILED(hr)) goto out;
2792 for (y = 0 ; y < ddsd.dwHeight; y++)
2794 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2796 for (x = 0; x < ddsd.dwWidth; x++)
2798 /* x stored in green component, y in blue. */
2799 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2800 *textureRow++ = color;
2804 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2805 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2808 for (i1 = 0; i1 < 4; i1++)
2810 memset(&ddbltfx, 0, sizeof(ddbltfx));
2811 ddbltfx.dwSize = sizeof(ddbltfx);
2812 U5(ddbltfx).dwFillColor = 0;
2813 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2814 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2817 loadpoint.x = loadpoint.y = 0;
2818 loadrect.left = 0;
2819 loadrect.top = 0;
2820 loadrect.right = 64;
2821 loadrect.bottom = 64;
2823 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2824 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2826 i = 0;
2827 for (i1 = 0; i1 < 8 && i < 4; i1++)
2829 DDSURFACEDESC2 ddsd2;
2831 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2832 ddsd.dwSize = sizeof(ddsd);
2833 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2834 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2836 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2837 ddsd2.dwSize = sizeof(ddsd2);
2838 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2839 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2841 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2843 diff_count = 0;
2845 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2846 ddsd.dwSize = sizeof(ddsd);
2847 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2848 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2849 if (FAILED(hr)) goto out;
2851 for (y = 0 ; y < ddsd.dwHeight; y++)
2853 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2855 for (x = 0; x < ddsd.dwWidth; x++)
2857 DWORD color = *textureRow++;
2859 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2860 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2862 if (color & 0xffffff) diff_count++;
2864 else
2866 DWORD r = (color & 0xff0000) >> 16;
2867 DWORD g = (color & 0xff00) >> 8;
2868 DWORD b = (color & 0xff);
2870 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2871 b != y + loadrect.top - loadpoint.y) diff_count++;
2876 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2877 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2879 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2881 i++;
2884 loadpoint.x /= 2;
2885 loadpoint.y /= 2;
2886 loadrect.top /= 2;
2887 loadrect.left /= 2;
2888 loadrect.right = (loadrect.right + 1) / 2;
2889 loadrect.bottom = (loadrect.bottom + 1) / 2;
2892 for (i = 0; i < 2; i++)
2894 for (i1 = 7; i1 >= 0; i1--)
2896 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2899 memset(texture_levels, 0, sizeof(texture_levels));
2902 /* Test palette copying. */
2903 for (i = 0; i < 2; i++)
2905 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2906 ddsd.dwSize = sizeof(ddsd);
2907 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2908 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2909 ddsd.dwWidth = 128;
2910 ddsd.dwHeight = 128;
2911 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2912 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2913 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2914 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2915 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2916 if (FAILED(hr)) goto out;
2918 /* Check the number of created mipmaps */
2919 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2920 ddsd.dwSize = sizeof(ddsd);
2921 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2922 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2923 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2924 if (U2(ddsd).dwMipMapCount != 8) goto out;
2926 for (i1 = 1; i1 < 8; i1++)
2928 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2929 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2930 if (FAILED(hr)) goto out;
2934 memset(table1, 0, sizeof(table1));
2935 for (i = 0; i < 3; i++)
2937 table1[0].peBlue = i + 1;
2938 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2939 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2940 if (FAILED(hr))
2942 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2943 goto out;
2947 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2948 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2950 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2951 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2953 hr = IDirectDrawSurface7_GetPalette(texture_levels[0][1], &palettes[4]);
2954 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2956 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2957 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2959 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2960 ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2961 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2962 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2964 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2965 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2967 memset(table1, 0, sizeof(table1));
2968 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2969 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2970 if (SUCCEEDED(hr))
2972 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2973 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2974 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2977 /* Test colorkey copying. */
2978 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2979 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2980 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2981 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2982 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2984 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2985 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2987 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2988 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2990 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2991 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2992 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2993 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2995 out:
2997 for (i = 0; i < 5; i++)
2999 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
3002 for (i = 0; i < 2; i++)
3004 for (i1 = 7; i1 >= 0; i1--)
3006 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
3010 for (i = 0; i < 2; i++)
3011 for (i1 = 5; i1 >= 0; i1--)
3012 for (i2 = 7; i2 >= 0; i2--)
3014 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
3018 static void SetMaterialTest(void)
3020 HRESULT rc;
3022 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
3023 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
3026 static void ComputeSphereVisibility(void)
3028 D3DMATRIX proj, view, world;
3029 D3DVALUE radius[3];
3030 D3DVECTOR center[3];
3031 DWORD result[3];
3032 HRESULT rc;
3034 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
3035 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
3036 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
3037 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
3039 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
3040 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
3041 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
3042 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
3044 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
3045 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
3046 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
3047 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
3049 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
3050 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3051 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3053 U1(center[0]).x=11.461533;
3054 U2(center[0]).y=-4.761727;
3055 U3(center[0]).z=-1.171646;
3057 radius[0]=38.252632;
3059 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3061 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3062 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
3064 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
3065 radius[0]=4.354097;
3066 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
3067 radius[1]=12.500704;
3068 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
3069 radius[2]=17.251318;
3071 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
3073 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3074 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3075 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3076 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
3077 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3078 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3080 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3081 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3082 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3083 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3085 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3086 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3087 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3088 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3090 U1(center[0]).x=0.0;
3091 U2(center[0]).y=0.0;
3092 U3(center[0]).z=0.05;
3094 radius[0]=0.04;
3096 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3097 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3099 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3101 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3102 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3104 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3105 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3106 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3107 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3109 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3111 U1(center[0]).x=0.0;
3112 U2(center[0]).y=0.0;
3113 U3(center[0]).z=0.5;
3115 radius[0]=0.5;
3117 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3119 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3120 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3122 U1(center[0]).x=0.0;
3123 U2(center[0]).y=0.0;
3124 U3(center[0]).z=0.0;
3126 radius[0]=0.0;
3128 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3130 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3131 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3133 U1(center[0]).x=-1.0;
3134 U2(center[0]).y=-1.0;
3135 U3(center[0]).z=0.50;
3137 radius[0]=0.25;
3139 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3141 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3142 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3144 U1(center[0]).x=-20.0;
3145 U2(center[0]).y=0.0;
3146 U3(center[0]).z=0.50;
3148 radius[0]=3.0;
3150 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3152 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3153 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3155 U1(center[0]).x=20.0;
3156 U2(center[0]).y=0.0;
3157 U3(center[0]).z=0.50;
3159 radius[0]=3.0f;
3161 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3163 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3164 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3166 U1(center[0]).x=0.0;
3167 U2(center[0]).y=-20.0;
3168 U3(center[0]).z=0.50;
3170 radius[0]=3.0;
3172 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3174 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3175 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3177 U1(center[0]).x=0.0;
3178 U2(center[0]).y=20.0;
3179 U3(center[0]).z=0.5;
3181 radius[0]=3.0;
3183 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3185 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3186 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3188 U1(center[0]).x=0.0;
3189 U2(center[0]).y=0.0;
3190 U3(center[0]).z=-20;
3192 radius[0]=3.0;
3194 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3196 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3197 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3199 U1(center[0]).x=0.0;
3200 U2(center[0]).y=0.0;
3201 U3(center[0]).z=20.0;
3203 radius[0]=3.0;
3205 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3207 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3208 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3211 static void SetRenderTargetTest(void)
3213 HRESULT hr;
3214 IDirectDrawSurface7 *newrt, *failrt, *oldrt, *temprt;
3215 D3DVIEWPORT7 vp;
3216 DDSURFACEDESC2 ddsd, ddsd2;
3217 DWORD stateblock;
3218 ULONG refcount;
3220 memset(&ddsd, 0, sizeof(ddsd));
3221 ddsd.dwSize = sizeof(ddsd);
3222 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3223 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3224 ddsd.dwWidth = 64;
3225 ddsd.dwHeight = 64;
3227 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3228 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3229 if(FAILED(hr))
3231 skip("Skipping SetRenderTarget test\n");
3232 return;
3235 memset(&ddsd2, 0, sizeof(ddsd2));
3236 ddsd2.dwSize = sizeof(ddsd2);
3237 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3238 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3239 ddsd2.dwWidth = 64;
3240 ddsd2.dwHeight = 64;
3241 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3242 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3243 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3244 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3246 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3247 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3249 memset(&vp, 0, sizeof(vp));
3250 vp.dwX = 10;
3251 vp.dwY = 10;
3252 vp.dwWidth = 246;
3253 vp.dwHeight = 246;
3254 vp.dvMinZ = 0.25;
3255 vp.dvMaxZ = 0.75;
3256 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3257 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3259 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3260 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3262 refcount = getRefcount((IUnknown*) oldrt);
3263 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3265 refcount = getRefcount((IUnknown*) failrt);
3266 ok(refcount == 1, "Refcount should be 1, returned is %d\n", refcount);
3268 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3269 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3271 refcount = getRefcount((IUnknown*) oldrt);
3272 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3274 refcount = getRefcount((IUnknown*) failrt);
3275 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3277 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &temprt);
3278 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3279 ok(failrt == temprt, "Wrong iface returned\n");
3281 refcount = getRefcount((IUnknown*) failrt);
3282 ok(refcount == 3, "Refcount should be 3, returned is %d\n", refcount);
3284 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3285 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3287 refcount = getRefcount((IUnknown*) failrt);
3288 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
3290 memset(&vp, 0xff, sizeof(vp));
3291 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3292 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3293 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3294 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3295 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3296 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3297 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3298 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3300 memset(&vp, 0, sizeof(vp));
3301 vp.dwX = 0;
3302 vp.dwY = 0;
3303 vp.dwWidth = 64;
3304 vp.dwHeight = 64;
3305 vp.dvMinZ = 0.0;
3306 vp.dvMaxZ = 1.0;
3307 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3308 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3310 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3311 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3312 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3313 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3315 /* Check this twice, before and after ending the stateblock */
3316 memset(&vp, 0xff, sizeof(vp));
3317 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3318 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3319 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3320 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3321 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3322 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3323 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3324 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3326 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3327 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3329 memset(&vp, 0xff, sizeof(vp));
3330 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3331 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3332 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3333 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3334 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3335 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3336 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3337 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3339 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3340 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3342 memset(&vp, 0, sizeof(vp));
3343 vp.dwX = 0;
3344 vp.dwY = 0;
3345 vp.dwWidth = 256;
3346 vp.dwHeight = 256;
3347 vp.dvMinZ = 0.0;
3348 vp.dvMaxZ = 0.0;
3349 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3350 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3352 IDirectDrawSurface7_Release(oldrt);
3353 IDirectDrawSurface7_Release(newrt);
3354 IDirectDrawSurface7_Release(failrt);
3355 IDirectDrawSurface7_Release(failrt);
3358 static const UINT *expect_messages;
3360 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3362 if (expect_messages && message == *expect_messages) ++expect_messages;
3364 return DefWindowProcA(hwnd, message, wparam, lparam);
3367 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
3368 * interface. This prevents subsequent SetCooperativeLevel() calls on a
3369 * different window from failing with DDERR_HWNDALREADYSET. */
3370 static void fix_wndproc(HWND window, LONG_PTR proc)
3372 IDirectDraw7 *ddraw7;
3373 HRESULT hr;
3375 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3376 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 object, hr %#x.\n", hr);
3377 if (FAILED(hr)) return;
3379 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
3380 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3381 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3382 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3383 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3385 IDirectDraw7_Release(ddraw7);
3388 static void test_wndproc(void)
3390 LONG_PTR proc, ddraw_proc;
3391 IDirectDraw7 *ddraw7;
3392 WNDCLASSA wc = {0};
3393 HWND window;
3394 HRESULT hr;
3395 ULONG ref;
3397 static const UINT messages[] =
3399 WM_WINDOWPOSCHANGING,
3400 WM_MOVE,
3401 WM_SIZE,
3402 WM_WINDOWPOSCHANGING,
3403 WM_ACTIVATE,
3404 WM_SETFOCUS,
3408 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
3409 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3410 if (FAILED(hr))
3412 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3413 return;
3416 wc.lpfnWndProc = test_proc;
3417 wc.lpszClassName = "d3d7_test_wndproc_wc";
3418 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3420 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3421 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3423 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3424 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3425 (LONG_PTR)test_proc, proc);
3427 expect_messages = messages;
3429 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3430 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3431 if (FAILED(hr))
3433 IDirectDraw7_Release(ddraw7);
3434 goto done;
3437 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3438 expect_messages = NULL;
3440 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3441 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3442 (LONG_PTR)test_proc, proc);
3444 ref = IDirectDraw7_Release(ddraw7);
3445 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3447 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3448 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3449 (LONG_PTR)test_proc, proc);
3451 /* DDSCL_NORMAL doesn't. */
3452 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3453 if (FAILED(hr))
3455 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3456 return;
3459 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3460 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3461 (LONG_PTR)test_proc, proc);
3463 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
3464 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3465 if (FAILED(hr))
3467 IDirectDraw7_Release(ddraw7);
3468 goto done;
3471 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3472 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3473 (LONG_PTR)test_proc, proc);
3475 ref = IDirectDraw7_Release(ddraw7);
3476 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3478 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3479 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3480 (LONG_PTR)test_proc, proc);
3482 /* The original window proc is only restored by ddraw if the current
3483 * window proc matches the one ddraw set. This also affects switching
3484 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
3485 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3486 if (FAILED(hr))
3488 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3489 return;
3492 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3493 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3494 (LONG_PTR)test_proc, proc);
3496 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3497 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3498 if (FAILED(hr))
3500 IDirectDraw7_Release(ddraw7);
3501 goto done;
3504 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3505 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3506 (LONG_PTR)test_proc, proc);
3507 ddraw_proc = proc;
3509 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3510 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3511 if (FAILED(hr))
3513 IDirectDraw7_Release(ddraw7);
3514 goto done;
3517 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3518 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3519 (LONG_PTR)test_proc, proc);
3521 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3522 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3523 if (FAILED(hr))
3525 IDirectDraw7_Release(ddraw7);
3526 goto done;
3529 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3530 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3531 (LONG_PTR)test_proc, proc);
3533 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
3534 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3535 if (FAILED(hr))
3537 IDirectDraw7_Release(ddraw7);
3538 goto done;
3541 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3542 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3543 (LONG_PTR)DefWindowProcA, proc);
3545 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3546 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3547 if (FAILED(hr))
3549 IDirectDraw7_Release(ddraw7);
3550 goto done;
3553 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
3554 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3555 (LONG_PTR)DefWindowProcA, proc);
3557 ref = IDirectDraw7_Release(ddraw7);
3558 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3560 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3561 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3562 (LONG_PTR)test_proc, proc);
3564 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3565 if (FAILED(hr))
3567 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3568 return;
3571 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3572 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3573 (LONG_PTR)test_proc, proc);
3575 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3576 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3577 if (FAILED(hr))
3579 IDirectDraw7_Release(ddraw7);
3580 goto done;
3583 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3584 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3585 (LONG_PTR)test_proc, proc);
3587 ref = IDirectDraw7_Release(ddraw7);
3588 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3590 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3591 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3592 (LONG_PTR)DefWindowProcA, proc);
3594 done:
3595 fix_wndproc(window, (LONG_PTR)test_proc);
3596 expect_messages = NULL;
3597 DestroyWindow(window);
3598 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3601 static void VertexBufferLockRest(void)
3603 D3DVERTEXBUFFERDESC desc;
3604 IDirect3DVertexBuffer7 *buffer;
3605 HRESULT hr;
3606 unsigned int i;
3607 void *data;
3608 const struct
3610 DWORD flags;
3611 const char *debug_string;
3612 HRESULT result;
3614 test_data[] =
3616 {0, "(none)", D3D_OK },
3617 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3618 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3619 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3620 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3621 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3622 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3623 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3625 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3626 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3627 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3630 memset(&desc, 0 , sizeof(desc));
3631 desc.dwSize = sizeof(desc);
3632 desc.dwCaps = 0;
3633 desc.dwFVF = D3DFVF_XYZ;
3634 desc.dwNumVertices = 64;
3635 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3636 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3638 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3640 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3641 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3642 test_data[i].debug_string, hr, test_data[i].result);
3643 if(SUCCEEDED(hr))
3645 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3646 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3647 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3651 IDirect3DVertexBuffer7_Release(buffer);
3654 static void FindDevice(void)
3656 static const struct
3658 const GUID *guid;
3659 int todo;
3660 } deviceGUIDs[] =
3662 {&IID_IDirect3DRampDevice, 1},
3663 {&IID_IDirect3DRGBDevice},
3666 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3667 &IID_IDirect3DRefDevice,
3668 &IID_IDirect3DTnLHalDevice,
3669 &IID_IDirect3DNullDevice};
3671 D3DFINDDEVICESEARCH search = {0};
3672 D3DFINDDEVICERESULT result = {0};
3673 IDirect3DDevice *d3dhal;
3674 HRESULT hr;
3675 int i;
3677 /* Test invalid parameters. */
3678 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3679 ok(hr == DDERR_INVALIDPARAMS,
3680 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3682 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3683 ok(hr == DDERR_INVALIDPARAMS,
3684 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3686 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3687 ok(hr == DDERR_INVALIDPARAMS,
3688 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3690 search.dwSize = 0;
3691 result.dwSize = 0;
3693 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3694 ok(hr == DDERR_INVALIDPARAMS,
3695 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3697 search.dwSize = sizeof(search) + 1;
3698 result.dwSize = sizeof(result) + 1;
3700 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3701 ok(hr == DDERR_INVALIDPARAMS,
3702 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3704 /* Specifying no flags is permitted. */
3705 search.dwSize = sizeof(search);
3706 search.dwFlags = 0;
3707 result.dwSize = sizeof(result);
3709 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3710 ok(hr == D3D_OK,
3711 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3713 /* Try an arbitrary non-device GUID. */
3714 search.dwSize = sizeof(search);
3715 search.dwFlags = D3DFDS_GUID;
3716 search.guid = IID_IDirect3D;
3717 result.dwSize = sizeof(result);
3719 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3720 ok(hr == DDERR_NOTFOUND,
3721 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3723 /* These GUIDs appear to be never present. */
3724 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3726 search.dwSize = sizeof(search);
3727 search.dwFlags = D3DFDS_GUID;
3728 search.guid = *nonexistent_deviceGUIDs[i];
3729 result.dwSize = sizeof(result);
3731 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3732 ok(hr == DDERR_NOTFOUND,
3733 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3736 /* The HAL device can only be enumerated if hardware acceleration is present. */
3737 search.dwSize = sizeof(search);
3738 search.dwFlags = D3DFDS_GUID;
3739 search.guid = IID_IDirect3DHALDevice;
3740 result.dwSize = sizeof(result);
3742 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3743 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3744 if (SUCCEEDED(hr))
3746 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3747 /* Currently Wine only supports the creation of one Direct3D device
3748 * for a given DirectDraw instance. */
3749 todo_wine
3750 ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
3751 "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3753 if (SUCCEEDED(hr))
3754 IDirect3DDevice_Release(d3dhal);
3756 else
3758 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3759 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3761 if (SUCCEEDED(hr))
3762 IDirect3DDevice_Release(d3dhal);
3765 /* These GUIDs appear to be always present. */
3766 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3768 search.dwSize = sizeof(search);
3769 search.dwFlags = D3DFDS_GUID;
3770 search.guid = *deviceGUIDs[i].guid;
3771 result.dwSize = sizeof(result);
3773 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3775 if (deviceGUIDs[i].todo)
3777 todo_wine
3778 ok(hr == D3D_OK,
3779 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3781 else
3783 ok(hr == D3D_OK,
3784 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3788 /* Curiously the color model criteria seem to be ignored. */
3789 search.dwSize = sizeof(search);
3790 search.dwFlags = D3DFDS_COLORMODEL;
3791 search.dcmColorModel = 0xdeadbeef;
3792 result.dwSize = sizeof(result);
3794 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3795 todo_wine
3796 ok(hr == D3D_OK,
3797 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3800 static void BackBuffer3DCreateSurfaceTest(void)
3802 DDSURFACEDESC ddsd;
3803 DDSURFACEDESC created_ddsd;
3804 DDSURFACEDESC2 ddsd2;
3805 IDirectDrawSurface *surf;
3806 IDirectDrawSurface4 *surf4;
3807 IDirectDrawSurface7 *surf7;
3808 HRESULT hr;
3809 IDirectDraw2 *dd2;
3810 IDirectDraw4 *dd4;
3811 IDirectDraw7 *dd7;
3812 DDCAPS ddcaps;
3813 IDirect3DDevice *d3dhal;
3815 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3816 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3818 memset(&ddcaps, 0, sizeof(ddcaps));
3819 ddcaps.dwSize = sizeof(DDCAPS);
3820 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3821 ok(SUCCEEDED(hr), "DirectDraw_GetCaps failed: 0x%08x\n", hr);
3822 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3824 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3825 return ;
3828 memset(&ddsd, 0, sizeof(ddsd));
3829 ddsd.dwSize = sizeof(ddsd);
3830 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3831 ddsd.dwWidth = 64;
3832 ddsd.dwHeight = 64;
3833 ddsd.ddsCaps.dwCaps = caps;
3834 memset(&ddsd2, 0, sizeof(ddsd2));
3835 ddsd2.dwSize = sizeof(ddsd2);
3836 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3837 ddsd2.dwWidth = 64;
3838 ddsd2.dwHeight = 64;
3839 ddsd2.ddsCaps.dwCaps = caps;
3840 memset(&created_ddsd, 0, sizeof(created_ddsd));
3841 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3843 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3844 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3845 if (surf != NULL)
3847 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3848 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3849 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3850 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3851 expected_caps);
3853 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3854 /* Currently Wine only supports the creation of one Direct3D device
3855 for a given DirectDraw instance. It has been created already
3856 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3857 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3859 if (SUCCEEDED(hr))
3860 IDirect3DDevice_Release(d3dhal);
3862 IDirectDrawSurface_Release(surf);
3865 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3866 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3868 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3869 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3870 DDERR_INVALIDCAPS, hr);
3872 IDirectDraw2_Release(dd2);
3874 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3875 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3877 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3878 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3879 DDERR_INVALIDCAPS, hr);
3881 IDirectDraw4_Release(dd4);
3883 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3884 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3886 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3887 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3888 DDERR_INVALIDCAPS, hr);
3890 IDirectDraw7_Release(dd7);
3893 static void BackBuffer3DAttachmentTest(void)
3895 HRESULT hr;
3896 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3897 DDSURFACEDESC ddsd;
3898 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3900 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3901 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3903 /* Perform attachment tests on a back-buffer */
3904 memset(&ddsd, 0, sizeof(ddsd));
3905 ddsd.dwSize = sizeof(ddsd);
3906 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3907 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3908 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3909 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3910 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3911 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3913 if (surface2 != NULL)
3915 /* Try a single primary and a two back buffers */
3916 memset(&ddsd, 0, sizeof(ddsd));
3917 ddsd.dwSize = sizeof(ddsd);
3918 ddsd.dwFlags = DDSD_CAPS;
3919 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3920 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3921 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3923 memset(&ddsd, 0, sizeof(ddsd));
3924 ddsd.dwSize = sizeof(ddsd);
3925 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3926 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3927 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3928 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3929 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3930 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3932 /* This one has a different size */
3933 memset(&ddsd, 0, sizeof(ddsd));
3934 ddsd.dwSize = sizeof(ddsd);
3935 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3936 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3937 ddsd.dwWidth = 128;
3938 ddsd.dwHeight = 128;
3939 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3940 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3942 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3943 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3944 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3945 if(SUCCEEDED(hr))
3947 /* Try the reverse without detaching first */
3948 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3949 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3950 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3951 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3953 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3954 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3955 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3956 if(SUCCEEDED(hr))
3958 /* Try to detach reversed */
3959 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3960 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3961 /* Now the proper detach */
3962 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3963 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3965 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3966 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3967 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3968 if(SUCCEEDED(hr))
3970 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3971 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3973 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3974 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3975 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3976 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3978 IDirectDrawSurface_Release(surface4);
3979 IDirectDrawSurface_Release(surface3);
3980 IDirectDrawSurface_Release(surface2);
3981 IDirectDrawSurface_Release(surface1);
3984 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
3985 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3987 DestroyWindow(window);
3990 static void test_window_style(void)
3992 LONG style, exstyle, tmp;
3993 RECT fullscreen_rect, r;
3994 IDirectDraw7 *ddraw7;
3995 HWND window;
3996 HRESULT hr;
3997 ULONG ref;
3999 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4000 if (FAILED(hr))
4002 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4003 return;
4006 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4007 0, 0, 100, 100, 0, 0, 0, 0);
4009 style = GetWindowLongA(window, GWL_STYLE);
4010 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
4011 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4013 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4014 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4015 if (FAILED(hr))
4017 IDirectDraw7_Release(ddraw7);
4018 DestroyWindow(window);
4019 return;
4022 tmp = GetWindowLongA(window, GWL_STYLE);
4023 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
4024 tmp = GetWindowLongA(window, GWL_EXSTYLE);
4025 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
4027 GetWindowRect(window, &r);
4028 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4029 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4030 r.left, r.top, r.right, r.bottom);
4031 GetClientRect(window, &r);
4032 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
4034 ref = IDirectDraw7_Release(ddraw7);
4035 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4037 DestroyWindow(window);
4040 static void test_redundant_mode_set(void)
4042 DDSURFACEDESC2 surface_desc = {0};
4043 IDirectDraw7 *ddraw7;
4044 HWND window;
4045 HRESULT hr;
4046 RECT r, s;
4047 ULONG ref;
4049 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4050 if (FAILED(hr))
4052 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4053 return;
4056 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
4057 0, 0, 100, 100, 0, 0, 0, 0);
4059 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4060 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4061 if (FAILED(hr))
4063 IDirectDraw7_Release(ddraw7);
4064 DestroyWindow(window);
4065 return;
4068 surface_desc.dwSize = sizeof(surface_desc);
4069 hr = IDirectDraw7_GetDisplayMode(ddraw7, &surface_desc);
4070 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
4072 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4073 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4074 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4076 GetWindowRect(window, &r);
4077 r.right /= 2;
4078 r.bottom /= 2;
4079 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
4080 GetWindowRect(window, &s);
4081 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4082 r.left, r.top, r.right, r.bottom,
4083 s.left, s.top, s.right, s.bottom);
4085 hr = IDirectDraw7_SetDisplayMode(ddraw7, surface_desc.dwWidth, surface_desc.dwHeight,
4086 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
4087 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4089 GetWindowRect(window, &s);
4090 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4091 r.left, r.top, r.right, r.bottom,
4092 s.left, s.top, s.right, s.bottom);
4094 ref = IDirectDraw7_Release(ddraw7);
4095 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4097 DestroyWindow(window);
4100 static SIZE screen_size;
4102 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
4104 if (message == WM_SIZE)
4106 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
4107 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
4110 return test_proc(hwnd, message, wparam, lparam);
4113 static void test_coop_level_mode_set(void)
4115 IDirectDrawSurface7 *primary;
4116 RECT fullscreen_rect, r, s;
4117 IDirectDraw7 *ddraw7;
4118 DDSURFACEDESC2 ddsd;
4119 WNDCLASSA wc = {0};
4120 HWND window;
4121 HRESULT hr;
4122 ULONG ref;
4124 static const UINT exclusive_messages[] =
4126 WM_WINDOWPOSCHANGING,
4127 WM_WINDOWPOSCHANGED,
4128 WM_SIZE,
4129 WM_DISPLAYCHANGE,
4133 static const UINT normal_messages[] =
4135 WM_DISPLAYCHANGE,
4139 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
4140 if (FAILED(hr))
4142 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4143 return;
4146 wc.lpfnWndProc = mode_set_proc;
4147 wc.lpszClassName = "d3d7_test_wndproc_wc";
4148 ok(RegisterClassA(&wc), "Failed to register window class.\n");
4150 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
4151 0, 0, 100, 100, 0, 0, 0, 0);
4153 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
4154 SetRect(&s, 0, 0, 640, 480);
4156 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
4157 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4158 if (FAILED(hr))
4160 IDirectDraw7_Release(ddraw7);
4161 goto done;
4164 GetWindowRect(window, &r);
4165 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4166 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4167 r.left, r.top, r.right, r.bottom);
4169 memset(&ddsd, 0, sizeof(ddsd));
4170 ddsd.dwSize = sizeof(ddsd);
4171 ddsd.dwFlags = DDSD_CAPS;
4172 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4174 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4175 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4176 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4177 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4178 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4179 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4180 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4181 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4183 GetWindowRect(window, &r);
4184 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4185 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4186 r.left, r.top, r.right, r.bottom);
4188 expect_messages = exclusive_messages;
4189 screen_size.cx = 0;
4190 screen_size.cy = 0;
4192 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4193 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4195 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4196 expect_messages = NULL;
4197 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
4198 "Expected screen size %ux%u, got %ux%u.\n",
4199 s.right, s.bottom, screen_size.cx, screen_size.cy);
4201 GetWindowRect(window, &r);
4202 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4203 s.left, s.top, s.right, s.bottom,
4204 r.left, r.top, r.right, r.bottom);
4206 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4207 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4208 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4209 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4210 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4211 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4212 IDirectDrawSurface7_Release(primary);
4214 memset(&ddsd, 0, sizeof(ddsd));
4215 ddsd.dwSize = sizeof(ddsd);
4216 ddsd.dwFlags = DDSD_CAPS;
4217 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4219 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4220 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4221 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4222 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4223 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4224 s.right - s.left, ddsd.dwWidth);
4225 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4226 s.bottom - s.top, ddsd.dwHeight);
4228 GetWindowRect(window, &r);
4229 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4230 s.left, s.top, s.right, s.bottom,
4231 r.left, r.top, r.right, r.bottom);
4233 expect_messages = exclusive_messages;
4234 screen_size.cx = 0;
4235 screen_size.cy = 0;
4237 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4238 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4240 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4241 expect_messages = NULL;
4242 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
4243 "Expected screen size %ux%u, got %ux%u.\n",
4244 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
4246 GetWindowRect(window, &r);
4247 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4248 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4249 r.left, r.top, r.right, r.bottom);
4251 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4252 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4253 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4254 s.right - s.left, ddsd.dwWidth);
4255 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4256 s.bottom - s.top, ddsd.dwHeight);
4257 IDirectDrawSurface7_Release(primary);
4259 memset(&ddsd, 0, sizeof(ddsd));
4260 ddsd.dwSize = sizeof(ddsd);
4261 ddsd.dwFlags = DDSD_CAPS;
4262 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4264 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4265 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4266 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4267 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4268 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4269 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4270 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4271 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4273 GetWindowRect(window, &r);
4274 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4275 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4276 r.left, r.top, r.right, r.bottom);
4278 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL);
4279 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4281 GetWindowRect(window, &r);
4282 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4283 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4284 r.left, r.top, r.right, r.bottom);
4286 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4287 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4288 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4289 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4290 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4291 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4292 IDirectDrawSurface7_Release(primary);
4294 memset(&ddsd, 0, sizeof(ddsd));
4295 ddsd.dwSize = sizeof(ddsd);
4296 ddsd.dwFlags = DDSD_CAPS;
4297 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4299 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4300 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4301 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4302 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4303 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4304 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4305 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4306 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4308 GetWindowRect(window, &r);
4309 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4310 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4311 r.left, r.top, r.right, r.bottom);
4313 expect_messages = normal_messages;
4314 screen_size.cx = 0;
4315 screen_size.cy = 0;
4317 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4318 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4320 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4321 expect_messages = NULL;
4322 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4324 GetWindowRect(window, &r);
4325 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4326 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4327 r.left, r.top, r.right, r.bottom);
4329 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4330 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4331 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4332 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4333 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4334 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4335 IDirectDrawSurface7_Release(primary);
4337 memset(&ddsd, 0, sizeof(ddsd));
4338 ddsd.dwSize = sizeof(ddsd);
4339 ddsd.dwFlags = DDSD_CAPS;
4340 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4342 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4343 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4344 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4345 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4346 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4347 s.right - s.left, ddsd.dwWidth);
4348 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4349 s.bottom - s.top, ddsd.dwHeight);
4351 GetWindowRect(window, &r);
4352 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4353 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4354 r.left, r.top, r.right, r.bottom);
4356 expect_messages = normal_messages;
4357 screen_size.cx = 0;
4358 screen_size.cy = 0;
4360 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4361 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4363 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4364 expect_messages = NULL;
4365 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4367 GetWindowRect(window, &r);
4368 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4369 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4370 r.left, r.top, r.right, r.bottom);
4372 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4373 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4374 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4375 s.right - s.left, ddsd.dwWidth);
4376 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4377 s.bottom - s.top, ddsd.dwHeight);
4378 IDirectDrawSurface7_Release(primary);
4380 memset(&ddsd, 0, sizeof(ddsd));
4381 ddsd.dwSize = sizeof(ddsd);
4382 ddsd.dwFlags = DDSD_CAPS;
4383 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4385 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4386 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4387 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4388 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4389 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4390 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4391 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4392 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4394 GetWindowRect(window, &r);
4395 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4396 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4397 r.left, r.top, r.right, r.bottom);
4399 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
4400 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
4401 * not DDSCL_FULLSCREEN. */
4402 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
4403 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
4405 GetWindowRect(window, &r);
4406 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4407 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4408 r.left, r.top, r.right, r.bottom);
4410 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4411 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4412 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4413 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4414 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4415 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4416 IDirectDrawSurface7_Release(primary);
4418 memset(&ddsd, 0, sizeof(ddsd));
4419 ddsd.dwSize = sizeof(ddsd);
4420 ddsd.dwFlags = DDSD_CAPS;
4421 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4423 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4424 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4425 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4426 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4427 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4428 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4429 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4430 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4432 GetWindowRect(window, &r);
4433 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4434 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4435 r.left, r.top, r.right, r.bottom);
4437 expect_messages = normal_messages;
4438 screen_size.cx = 0;
4439 screen_size.cy = 0;
4441 hr = IDirectDraw7_SetDisplayMode(ddraw7, 640, 480, 32, 0, 0);
4442 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
4444 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4445 expect_messages = NULL;
4446 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4448 GetWindowRect(window, &r);
4449 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4450 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4451 r.left, r.top, r.right, r.bottom);
4453 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4454 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4455 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4456 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4457 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4458 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4459 IDirectDrawSurface7_Release(primary);
4461 memset(&ddsd, 0, sizeof(ddsd));
4462 ddsd.dwSize = sizeof(ddsd);
4463 ddsd.dwFlags = DDSD_CAPS;
4464 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4466 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4467 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4468 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4469 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4470 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4471 s.right - s.left, ddsd.dwWidth);
4472 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4473 s.bottom - s.top, ddsd.dwHeight);
4475 GetWindowRect(window, &r);
4476 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4477 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4478 r.left, r.top, r.right, r.bottom);
4480 expect_messages = normal_messages;
4481 screen_size.cx = 0;
4482 screen_size.cy = 0;
4484 hr = IDirectDraw_RestoreDisplayMode(ddraw7);
4485 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
4487 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
4488 expect_messages = NULL;
4489 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
4491 GetWindowRect(window, &r);
4492 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4493 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4494 r.left, r.top, r.right, r.bottom);
4496 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4497 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4498 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
4499 s.right - s.left, ddsd.dwWidth);
4500 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
4501 s.bottom - s.top, ddsd.dwHeight);
4502 IDirectDrawSurface7_Release(primary);
4504 memset(&ddsd, 0, sizeof(ddsd));
4505 ddsd.dwSize = sizeof(ddsd);
4506 ddsd.dwFlags = DDSD_CAPS;
4507 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4509 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd, &primary, NULL);
4510 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
4511 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
4512 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
4513 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
4514 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
4515 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
4516 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
4517 IDirectDrawSurface7_Release(primary);
4519 GetWindowRect(window, &r);
4520 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4521 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4522 r.left, r.top, r.right, r.bottom);
4524 ref = IDirectDraw7_Release(ddraw7);
4525 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
4527 GetWindowRect(window, &r);
4528 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
4529 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
4530 r.left, r.top, r.right, r.bottom);
4532 done:
4533 expect_messages = NULL;
4534 DestroyWindow(window);
4535 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
4538 static void dump_format(const DDPIXELFORMAT *fmt)
4540 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %08x\n", fmt->dwFlags, fmt->dwFourCC,
4541 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
4542 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
4543 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
4546 static HRESULT WINAPI enum_z_fmt_cb(DDPIXELFORMAT *fmt, void *ctx)
4548 static const DDPIXELFORMAT formats[] =
4551 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4552 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
4555 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4556 {32}, {0}, {0xffffff00}, {0x00000000}, {0x00000000}
4559 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4560 {32}, {8}, {0xffffff00}, {0x000000ff}, {0x00000000}
4563 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4564 {32}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4567 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0,
4568 {32}, {8}, {0x00ffffff}, {0xff000000}, {0x00000000}
4571 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4572 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
4575 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4576 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
4579 unsigned int *count = ctx, i, expected_pitch;
4580 DDSURFACEDESC2 ddsd;
4581 IDirectDrawSurface7 *surface;
4582 HRESULT hr;
4583 (*count)++;
4585 memset(&ddsd, 0, sizeof(ddsd));
4586 ddsd.dwSize = sizeof(ddsd);
4587 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
4588 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4589 U4(ddsd).ddpfPixelFormat = *fmt;
4590 ddsd.dwWidth = 1024;
4591 ddsd.dwHeight = 1024;
4592 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface, NULL);
4593 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed, hr %#x.\n", hr);
4594 memset(&ddsd, 0, sizeof(ddsd));
4595 ddsd.dwSize = sizeof(ddsd);
4596 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
4597 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc failed, hr %#x.\n", hr);
4598 IDirectDrawSurface7_Release(surface);
4600 ok(ddsd.dwFlags & DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT is not set\n");
4601 ok(!(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH), "DDSD_ZBUFFERBITDEPTH is set\n");
4603 /* 24 bit unpadded depth buffers are actually padded(Geforce 9600, Win7,
4604 * Radeon 9000M WinXP) */
4605 if (U1(*fmt).dwZBufferBitDepth == 24) expected_pitch = ddsd.dwWidth * 4;
4606 else expected_pitch = ddsd.dwWidth * U1(*fmt).dwZBufferBitDepth / 8;
4608 /* Some formats(16 bit depth without stencil) return pitch 0
4610 * The Radeon X1600 Catalyst 10.2 Windows XP driver returns an otherwise sane
4611 * pitch with an extra 128 bytes, regardless of the format and width */
4612 if (U1(ddsd).lPitch != 0 && U1(ddsd).lPitch != expected_pitch
4613 && !broken(U1(ddsd).lPitch == expected_pitch + 128))
4615 ok(0, "Z buffer pitch is %u, expected %u\n", U1(ddsd).lPitch, expected_pitch);
4616 dump_format(fmt);
4619 for (i = 0; i < (sizeof(formats)/sizeof(*formats)); i++)
4621 if (memcmp(&formats[i], fmt, fmt->dwSize) == 0) return DDENUMRET_OK;
4624 ok(0, "Unexpected Z format enumerated\n");
4625 dump_format(fmt);
4627 return DDENUMRET_OK;
4630 static void z_format_test(void)
4632 unsigned int count = 0;
4633 HRESULT hr;
4635 hr = IDirect3D7_EnumZBufferFormats(lpD3D, &IID_IDirect3DHALDevice, enum_z_fmt_cb, &count);
4636 if (hr == DDERR_NOZBUFFERHW)
4638 skip("Z buffers not supported, skipping Z buffer format test\n");
4639 return;
4642 ok(SUCCEEDED(hr), "IDirect3D7_EnumZBufferFormats failed, hr %#x.\n", hr);
4643 ok(count, "Expected at least one supported Z Buffer format\n");
4646 static void test_initialize(void)
4648 IDirectDraw7 *ddraw7;
4649 IDirectDraw4 *ddraw4;
4650 IDirectDraw2 *ddraw2;
4651 IDirectDraw *ddraw1;
4652 IDirect3D *d3d1;
4653 HRESULT hr;
4655 /* IDirectDraw */
4656 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4658 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4659 return;
4662 hr = IDirectDraw_Initialize(ddraw1, NULL);
4663 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4664 IDirectDraw_Release(ddraw1);
4666 CoInitialize(NULL);
4667 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw1);
4668 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4669 hr = IDirectDraw_Initialize(ddraw1, NULL);
4670 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4671 hr = IDirectDraw_Initialize(ddraw1, NULL);
4672 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4673 IDirectDraw_Release(ddraw1);
4674 CoUninitialize();
4676 hr = DirectDrawCreate(NULL, &ddraw1, NULL);
4677 ok(SUCCEEDED(hr), "Failed to create IDirectDraw object, hr %#x.\n", hr);
4679 /* IDirectDraw2 */
4680 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4682 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4683 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4684 IDirectDraw2_Release(ddraw2);
4686 CoInitialize(NULL);
4687 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw2, (void **)&ddraw2);
4688 ok(SUCCEEDED(hr), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr);
4689 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4690 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4691 hr = IDirectDraw2_Initialize(ddraw2, NULL);
4692 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4693 IDirectDraw2_Release(ddraw2);
4694 CoUninitialize();
4696 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4698 /* IDirectDraw4 */
4699 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4701 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4702 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4703 IDirectDraw4_Release(ddraw4);
4705 CoInitialize(NULL);
4706 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw4, (void **)&ddraw4);
4707 ok(SUCCEEDED(hr), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr);
4708 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4709 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4710 hr = IDirectDraw4_Initialize(ddraw4, NULL);
4711 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4712 IDirectDraw4_Release(ddraw4);
4713 CoUninitialize();
4715 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4717 /* IDirect3D */
4718 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirect3D, (void **)&d3d1)))
4720 IDirectDraw *ddraw;
4722 hr = IDirect3D_Initialize(d3d1, NULL);
4723 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4724 IDirect3D_Release(d3d1);
4726 if (0) /* This crashes on the W2KPROSP4 testbot. */
4728 CoInitialize(NULL);
4729 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirect3D, (void **)&d3d1);
4730 ok(hr == E_NOINTERFACE, "CoCreateInstance returned hr %#x, expected E_NOINTERFACE.\n", hr);
4731 CoUninitialize();
4734 CoInitialize(NULL);
4735 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw, (void **)&ddraw);
4736 ok(SUCCEEDED(hr), "Failed to create IDirectDraw instance, hr %#x.\n", hr);
4737 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D, (void **)&d3d1);
4738 ok(SUCCEEDED(hr), "Failed to query IDirect3D interface, hr %#x.\n", hr);
4739 IDirectDraw_Release(ddraw);
4740 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
4741 hr = IDirect3D_Initialize(d3d1, NULL);
4742 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4743 hr = IDirectDraw_Initialize(ddraw, NULL);
4744 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4745 hr = IDirectDraw_Initialize(ddraw, NULL);
4746 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4747 IDirect3D_Release(d3d1);
4748 CoUninitialize();
4750 else skip("Failed to query IDirect3D interface, skipping tests.\n");
4752 IDirectDraw_Release(ddraw1);
4754 /* IDirectDraw7 */
4755 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4757 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4758 return;
4760 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4761 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
4762 IDirectDraw7_Release(ddraw7);
4764 CoInitialize(NULL);
4765 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw7, (void **)&ddraw7);
4766 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr);
4767 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4768 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
4769 hr = IDirectDraw7_Initialize(ddraw7, NULL);
4770 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
4771 IDirectDraw7_Release(ddraw7);
4772 CoUninitialize();
4775 static void test_coop_level_surf_create(void)
4777 IDirectDrawSurface7 *surface7;
4778 IDirectDrawSurface4 *surface4;
4779 IDirectDrawSurface *surface1;
4780 IDirectDraw7 *ddraw7;
4781 IDirectDraw4 *ddraw4;
4782 IDirectDraw2 *ddraw2;
4783 IDirectDraw *ddraw1;
4784 DDSURFACEDESC2 ddsd2;
4785 DDSURFACEDESC ddsd;
4786 HRESULT hr;
4788 /* IDirectDraw */
4789 if (FAILED(hr = DirectDrawCreate(NULL, &ddraw1, NULL)))
4791 skip("Failed to create IDirectDraw object (%#x), skipping tests.\n", hr);
4792 return;
4795 memset(&ddsd, 0, sizeof(ddsd));
4796 ddsd.dwSize = sizeof(ddsd);
4797 ddsd.dwFlags = DDSD_CAPS;
4798 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4799 hr = IDirectDraw_CreateSurface(ddraw1, &ddsd, &surface1, NULL);
4800 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4802 /* IDirectDraw2 */
4803 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw2, (void **)&ddraw2)))
4805 memset(&ddsd, 0, sizeof(ddsd));
4806 ddsd.dwSize = sizeof(ddsd);
4807 ddsd.dwFlags = DDSD_CAPS;
4808 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4809 hr = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &surface1, NULL);
4810 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4812 IDirectDraw2_Release(ddraw2);
4814 else skip("Failed to query IDirectDraw2 interface, skipping tests.\n");
4816 /* IDirectDraw4 */
4817 if (SUCCEEDED(IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4)))
4819 memset(&ddsd2, 0, sizeof(ddsd2));
4820 ddsd2.dwSize = sizeof(ddsd2);
4821 ddsd2.dwFlags = DDSD_CAPS;
4822 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4823 hr = IDirectDraw4_CreateSurface(ddraw4, &ddsd2, &surface4, NULL);
4824 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4826 IDirectDraw4_Release(ddraw4);
4828 else skip("Failed to query IDirectDraw4 interface, skipping tests.\n");
4830 IDirectDraw_Release(ddraw1);
4832 /* IDirectDraw7 */
4833 if (FAILED(hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL)))
4835 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
4836 return;
4839 memset(&ddsd2, 0, sizeof(ddsd2));
4840 ddsd2.dwSize = sizeof(ddsd2);
4841 ddsd2.dwFlags = DDSD_CAPS;
4842 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4843 hr = IDirectDraw7_CreateSurface(ddraw7, &ddsd2, &surface7, NULL);
4844 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
4846 IDirectDraw7_Release(ddraw7);
4849 static void test_get_caps1(void)
4851 D3DDEVICEDESC hw_caps, hel_caps;
4852 HRESULT hr;
4853 unsigned int i;
4855 memset(&hw_caps, 0, sizeof(hw_caps));
4856 hw_caps.dwSize = sizeof(hw_caps);
4857 hw_caps.dwFlags = 0xdeadbeef;
4858 memset(&hel_caps, 0, sizeof(hel_caps));
4859 hel_caps.dwSize = sizeof(hel_caps);
4860 hel_caps.dwFlags = 0xdeadc0de;
4862 /* NULL pointers */
4863 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, NULL);
4864 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4865 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4866 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, NULL, &hel_caps);
4867 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
4868 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4870 /* Successful call: Both are modified */
4871 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4872 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
4873 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
4874 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
4876 memset(&hw_caps, 0, sizeof(hw_caps));
4877 hw_caps.dwSize = sizeof(hw_caps);
4878 hw_caps.dwFlags = 0xdeadbeef;
4879 memset(&hel_caps, 0, sizeof(hel_caps));
4880 /* Keep dwSize at 0 */
4881 hel_caps.dwFlags = 0xdeadc0de;
4883 /* If one is invalid the call fails */
4884 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4885 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4886 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4887 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4888 hel_caps.dwSize = sizeof(hel_caps);
4889 hw_caps.dwSize = sizeof(hw_caps) + 1;
4890 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4891 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
4892 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
4893 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
4895 for (i = 0; i < 1024; i++)
4897 memset(&hw_caps, 0xfe, sizeof(hw_caps));
4898 memset(&hel_caps, 0xfe, sizeof(hel_caps));
4899 hw_caps.dwSize = hel_caps.dwSize = i;
4900 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4901 switch (i)
4903 /* D3DDEVICEDESCSIZE in old sdk versions */
4904 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
4905 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "hw_caps.dwMinTextureWidth was modified: %#x.\n",
4906 hw_caps.dwMinTextureWidth);
4907 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "hel_caps.dwMinTextureWidth was modified: %#x.\n",
4908 hel_caps.dwMinTextureWidth);
4909 /* drop through */
4910 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
4911 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "hw_caps.dwMaxTextureRepeat was modified: %#x.\n",
4912 hw_caps.dwMaxTextureRepeat);
4913 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "hel_caps.dwMaxTextureRepeat was modified: %#x.\n",
4914 hel_caps.dwMaxTextureRepeat);
4915 /* drop through */
4916 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
4917 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
4918 break;
4920 default:
4921 ok(hr == DDERR_INVALIDPARAMS,
4922 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
4923 break;
4927 /* Different valid sizes are OK */
4928 hw_caps.dwSize = 172;
4929 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
4930 hr = IDirect3DDevice_GetCaps(Direct3DDevice1, &hw_caps, &hel_caps);
4931 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
4934 static void test_get_caps7(void)
4936 HRESULT hr;
4937 D3DDEVICEDESC7 desc;
4939 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, NULL);
4940 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7::GetCaps(NULL) returned hr %#x, expected INVALIDPARAMS.\n", hr);
4942 memset(&desc, 0, sizeof(desc));
4943 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &desc);
4944 ok(hr == D3D_OK, "IDirect3DDevice7::GetCaps(non-NULL) returned hr %#x, expected D3D_OK.\n", hr);
4946 /* There's no dwSize in D3DDEVICEDESC7 */
4949 struct d3d2_test_context
4951 IDirectDraw *ddraw;
4952 IDirect3D2 *d3d;
4953 IDirectDrawSurface *surface;
4954 IDirect3DDevice2 *device;
4955 IDirect3DViewport2 *viewport;
4958 static void d3d2_release_objects(struct d3d2_test_context *context)
4960 LONG ref;
4961 HRESULT hr;
4963 if (context->viewport)
4965 hr = IDirect3DDevice2_DeleteViewport(context->device, context->viewport);
4966 ok(hr == D3D_OK, "DeleteViewport returned %08x.\n", hr);
4967 ref = IDirect3DViewport2_Release(context->viewport);
4968 ok(ref == 0, "Viewport has reference count %d, expected 0.\n", ref);
4970 if (context->device)
4972 ref = IDirect3DDevice2_Release(context->device);
4973 ok(ref == 0, "Device has reference count %d, expected 0.\n", ref);
4975 if (context->surface)
4977 ref = IDirectDrawSurface_Release(context->surface);
4978 ok(ref == 0, "Surface has reference count %d, expected 0.\n", ref);
4980 if (context->d3d)
4982 ref = IDirect3D2_Release(context->d3d);
4983 ok(ref == 1, "IDirect3D2 has reference count %d, expected 1.\n", ref);
4985 if (context->ddraw)
4987 ref = IDirectDraw_Release(context->ddraw);
4988 ok(ref == 0, "DDraw has reference count %d, expected 0.\n", ref);
4992 static BOOL d3d2_create_objects(struct d3d2_test_context *context)
4994 HRESULT hr;
4995 DDSURFACEDESC ddsd;
4996 D3DVIEWPORT vp_data;
4998 memset(context, 0, sizeof(*context));
5000 hr = DirectDrawCreate(NULL, &context->ddraw, NULL);
5001 ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate failed: %08x.\n", hr);
5002 if (!context->ddraw) goto error;
5004 hr = IDirectDraw_SetCooperativeLevel(context->ddraw, NULL, DDSCL_NORMAL);
5005 ok(hr == DD_OK, "SetCooperativeLevel failed: %08x.\n", hr);
5006 if (FAILED(hr)) goto error;
5008 hr = IDirectDraw_QueryInterface(context->ddraw, &IID_IDirect3D2, (void**) &context->d3d);
5009 ok(hr == DD_OK || hr == E_NOINTERFACE, "QueryInterface failed: %08x.\n", hr);
5010 if (!context->d3d) goto error;
5012 memset(&ddsd, 0, sizeof(ddsd));
5013 ddsd.dwSize = sizeof(ddsd);
5014 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
5015 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
5016 ddsd.dwWidth = 256;
5017 ddsd.dwHeight = 256;
5018 IDirectDraw_CreateSurface(context->ddraw, &ddsd, &context->surface, NULL);
5019 if (!context->surface)
5021 skip("DDSCAPS_3DDEVICE surface not available.\n");
5022 goto error;
5025 hr = IDirect3D2_CreateDevice(context->d3d, &IID_IDirect3DHALDevice, context->surface, &context->device);
5026 ok(hr == D3D_OK || hr == E_OUTOFMEMORY || hr == E_NOINTERFACE, "CreateDevice failed: %08x.\n", hr);
5027 if (!context->device) goto error;
5029 hr = IDirect3D2_CreateViewport(context->d3d, &context->viewport, NULL);
5030 ok(hr == D3D_OK, "CreateViewport failed: %08x.\n", hr);
5031 if (!context->viewport) goto error;
5033 hr = IDirect3DDevice2_AddViewport(context->device, context->viewport);
5034 ok(hr == D3D_OK, "AddViewport returned %08x.\n", hr);
5035 vp_data.dwSize = sizeof(vp_data);
5036 vp_data.dwX = 0;
5037 vp_data.dwY = 0;
5038 vp_data.dwWidth = 256;
5039 vp_data.dwHeight = 256;
5040 vp_data.dvScaleX = 1;
5041 vp_data.dvScaleY = 1;
5042 vp_data.dvMaxX = 256;
5043 vp_data.dvMaxY = 256;
5044 vp_data.dvMinZ = 0;
5045 vp_data.dvMaxZ = 1;
5046 hr = IDirect3DViewport2_SetViewport(context->viewport, &vp_data);
5047 ok(hr == D3D_OK, "SetViewport returned %08x.\n", hr);
5049 return TRUE;
5051 error:
5052 d3d2_release_objects(context);
5053 return FALSE;
5056 static void test_get_caps2(const struct d3d2_test_context *context)
5058 D3DDEVICEDESC hw_caps, hel_caps;
5059 HRESULT hr;
5060 unsigned int i;
5062 memset(&hw_caps, 0, sizeof(hw_caps));
5063 hw_caps.dwSize = sizeof(hw_caps);
5064 hw_caps.dwFlags = 0xdeadbeef;
5065 memset(&hel_caps, 0, sizeof(hel_caps));
5066 hel_caps.dwSize = sizeof(hel_caps);
5067 hel_caps.dwFlags = 0xdeadc0de;
5069 /* NULL pointers */
5070 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, NULL);
5071 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hel caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
5072 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
5073 hr = IDirect3DDevice2_GetCaps(context->device, NULL, &hel_caps);
5074 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with NULL hw caps returned hr %#x, expected INVALIDPARAMS.\n", hr);
5075 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
5077 /* Successful call: Both are modified */
5078 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
5079 ok(hr == D3D_OK, "GetCaps with correct size returned hr %#x, expected D3D_OK.\n", hr);
5080 ok(hw_caps.dwFlags != 0xdeadbeef, "hw_caps.dwFlags was not modified: %#x.\n", hw_caps.dwFlags);
5081 ok(hel_caps.dwFlags != 0xdeadc0de, "hel_caps.dwFlags was not modified: %#x.\n", hel_caps.dwFlags);
5083 memset(&hw_caps, 0, sizeof(hw_caps));
5084 hw_caps.dwSize = sizeof(hw_caps);
5085 hw_caps.dwFlags = 0xdeadbeef;
5086 memset(&hel_caps, 0, sizeof(hel_caps));
5087 /* Keep dwSize at 0 */
5088 hel_caps.dwFlags = 0xdeadc0de;
5090 /* If one is invalid the call fails */
5091 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
5092 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hel_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
5093 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
5094 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
5095 hel_caps.dwSize = sizeof(hel_caps);
5096 hw_caps.dwSize = sizeof(hw_caps) + 1;
5097 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
5098 ok(hr == DDERR_INVALIDPARAMS, "GetCaps with invalid hw_caps size returned hr %#x, expected INVALIDPARAMS.\n", hr);
5099 ok(hw_caps.dwFlags == 0xdeadbeef, "hw_caps.dwFlags was modified: %#x.\n", hw_caps.dwFlags);
5100 ok(hel_caps.dwFlags == 0xdeadc0de, "hel_caps.dwFlags was modified: %#x.\n", hel_caps.dwFlags);
5102 for (i = 0; i < 1024; i++)
5104 memset(&hw_caps, 0xfe, sizeof(hw_caps));
5105 memset(&hel_caps, 0xfe, sizeof(hel_caps));
5106 hw_caps.dwSize = hel_caps.dwSize = i;
5107 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
5108 switch (i)
5110 /* D3DDEVICEDESCSIZE in old sdk versions */
5111 case FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth): /* 172, DirectX 3, IDirect3DDevice1 */
5112 ok(hw_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
5113 hw_caps.dwMinTextureWidth);
5114 ok(hel_caps.dwMinTextureWidth == 0xfefefefe, "dwMinTextureWidth was modified: %#x.\n",
5115 hel_caps.dwMinTextureWidth);
5116 /* drop through */
5117 case FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat): /* 204, DirectX 5, IDirect3DDevice2 */
5118 ok(hw_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
5119 hw_caps.dwMaxTextureRepeat);
5120 ok(hel_caps.dwMaxTextureRepeat == 0xfefefefe, "dwMaxTextureRepeat was modified: %#x.\n",
5121 hel_caps.dwMaxTextureRepeat);
5122 /* drop through */
5123 case sizeof(D3DDEVICEDESC): /* 252, DirectX 6, IDirect3DDevice3 */
5124 ok(hr == D3D_OK, "GetCaps with size %u returned hr %#x, expected D3D_OK.\n", i, hr);
5125 break;
5127 default:
5128 ok(hr == DDERR_INVALIDPARAMS,
5129 "GetCaps with size %u returned hr %#x, expected DDERR_INVALIDPARAMS.\n", i, hr);
5130 break;
5134 /* Different valid sizes are OK */
5135 hw_caps.dwSize = 172;
5136 hel_caps.dwSize = sizeof(D3DDEVICEDESC);
5137 hr = IDirect3DDevice2_GetCaps(context->device, &hw_caps, &hel_caps);
5138 ok(hr == D3D_OK, "GetCaps with different sizes returned hr %#x, expected D3D_OK.\n", hr);
5141 START_TEST(d3d)
5143 struct d3d2_test_context d3d2_context;
5144 void (* const d3d2_tests[])(const struct d3d2_test_context *) =
5146 test_get_caps2
5148 unsigned int i;
5150 init_function_pointers();
5151 if(!pDirectDrawCreateEx) {
5152 win_skip("function DirectDrawCreateEx not available\n");
5153 return;
5156 if(!CreateDirect3D()) {
5157 skip("Skipping d3d7 tests\n");
5158 } else {
5159 LightTest();
5160 ProcessVerticesTest();
5161 StateTest();
5162 SceneTest();
5163 LimitTest();
5164 D3D7EnumTest();
5165 D3D7EnumLifetimeTest();
5166 SetMaterialTest();
5167 ComputeSphereVisibility();
5168 CapsTest();
5169 VertexBufferDescTest();
5170 D3D7_OldRenderStateTest();
5171 DeviceLoadTest();
5172 SetRenderTargetTest();
5173 VertexBufferLockRest();
5174 z_format_test();
5175 test_get_caps7();
5176 ReleaseDirect3D();
5179 for (i = 0; i < (sizeof(d3d2_tests) / sizeof(*d3d2_tests)); i++)
5181 if (!d3d2_create_objects(&d3d2_context))
5183 ok(!i, "Unexpected d3d2 initialization failure.\n");
5184 skip("Skipping d3d2 tests.\n");
5185 break;
5187 d3d2_tests[i](&d3d2_context);
5188 d3d2_release_objects(&d3d2_context);
5191 if (!D3D1_createObjects()) {
5192 skip("Skipping d3d1 tests\n");
5193 } else {
5194 Direct3D1Test();
5195 TextureLoadTest();
5196 ViewportTest();
5197 FindDevice();
5198 BackBuffer3DCreateSurfaceTest();
5199 BackBuffer3DAttachmentTest();
5200 test_get_caps1();
5201 D3D1_releaseObjects();
5204 test_wndproc();
5205 test_window_style();
5206 test_redundant_mode_set();
5207 test_coop_level_mode_set();
5208 test_initialize();
5209 test_coop_level_surf_create();