push ac4b6ebdd3fd886d6a18959265755579ed195b88
[wine/hacks.git] / dlls / ddraw / tests / d3d.c
blob134db9f14eace3bf26748ab22a738a5fc252c5cb
1 /*
2 * Some unit tests for d3d functions
4 * Copyright (C) 2005 Antoine Chavasse
5 * Copyright (C) 2006 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 <assert.h>
26 #include "wine/test.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 /* To compare bad floating point numbers. Not the ideal way to do it,
58 * but it should be enough for here */
59 #define comparefloat(a, b) ( (((a) - (b)) < 0.0001) && (((a) - (b)) > -0.0001) )
61 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
63 typedef struct _VERTEX
65 float x, y, z; /* position */
66 } VERTEX, *LPVERTEX;
68 typedef struct _TVERTEX
70 float x, y, z; /* position */
71 float rhw;
72 } TVERTEX, *LPTVERTEX;
75 static void init_function_pointers(void)
77 HMODULE hmod = GetModuleHandleA("ddraw.dll");
78 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
82 static ULONG getRefcount(IUnknown *iface)
84 IUnknown_AddRef(iface);
85 return IUnknown_Release(iface);
89 static BOOL CreateDirect3D(void)
91 HRESULT rc;
92 DDSURFACEDESC2 ddsd;
94 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
95 &IID_IDirectDraw7, NULL);
96 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
97 if (!lpDD) {
98 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
99 return FALSE;
102 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
103 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
105 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
106 if (rc == E_NOINTERFACE) return FALSE;
107 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
109 memset(&ddsd, 0, sizeof(ddsd));
110 ddsd.dwSize = sizeof(ddsd);
111 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
112 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
113 ddsd.dwWidth = 256;
114 ddsd.dwHeight = 256;
115 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
116 if (FAILED(rc))
117 return FALSE;
119 memset(&ddsd, 0, sizeof(ddsd));
120 ddsd.dwSize = sizeof(ddsd);
121 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
122 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
123 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
124 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
125 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
126 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
127 ddsd.dwWidth = 256;
128 ddsd.dwHeight = 256;
129 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
130 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
131 if (FAILED(rc)) {
132 lpDDSdepth = NULL;
133 } else {
134 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
135 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
136 if (FAILED(rc))
137 return FALSE;
140 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
141 &lpD3DDevice);
142 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
143 if (!lpD3DDevice) {
144 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
145 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
146 &lpD3DDevice);
147 if (!lpD3DDevice) {
148 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
149 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
150 &lpD3DDevice);
151 if (!lpD3DDevice) {
152 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
153 return FALSE;
158 return TRUE;
161 static void ReleaseDirect3D(void)
163 if (lpD3DDevice != NULL)
165 IDirect3DDevice7_Release(lpD3DDevice);
166 lpD3DDevice = NULL;
169 if (lpDDSdepth != NULL)
171 IDirectDrawSurface_Release(lpDDSdepth);
172 lpDDSdepth = NULL;
175 if (lpDDS != NULL)
177 IDirectDrawSurface_Release(lpDDS);
178 lpDDS = NULL;
181 if (lpD3D != NULL)
183 IDirect3D7_Release(lpD3D);
184 lpD3D = NULL;
187 if (lpDD != NULL)
189 IDirectDraw_Release(lpDD);
190 lpDD = NULL;
194 static void LightTest(void)
196 HRESULT rc;
197 D3DLIGHT7 light;
198 D3DLIGHT7 defaultlight;
199 BOOL bEnabled = FALSE;
200 float one = 1.0f;
201 float zero= 0.0f;
202 D3DMATERIAL7 mat;
203 BOOL enabled;
204 unsigned int i;
205 D3DDEVICEDESC7 caps;
207 /* Set a few lights with funky indices. */
208 memset(&light, 0, sizeof(light));
209 light.dltType = D3DLIGHT_DIRECTIONAL;
210 U1(light.dcvDiffuse).r = 0.5f;
211 U2(light.dcvDiffuse).g = 0.6f;
212 U3(light.dcvDiffuse).b = 0.7f;
213 U2(light.dvDirection).y = 1.f;
215 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
216 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
217 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
218 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
219 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
220 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
223 /* Try to retrieve a light beyond the indices of the lights that have
224 been set. */
225 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
226 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
227 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
228 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
231 /* Try to retrieve one of the lights that have been set */
232 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
233 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
236 /* Enable a light that have been previously set. */
237 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
238 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
241 /* Enable some lights that have not been previously set, and verify that
242 they have been initialized with proper default values. */
243 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
244 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
245 U1(defaultlight.dcvDiffuse).r = 1.f;
246 U2(defaultlight.dcvDiffuse).g = 1.f;
247 U3(defaultlight.dcvDiffuse).b = 1.f;
248 U3(defaultlight.dvDirection).z = 1.f;
250 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
251 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
252 memset(&light, 0, sizeof(D3DLIGHT7));
253 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
254 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
255 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
256 "light data doesn't match expected default values\n" );
258 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
259 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
260 memset(&light, 0, sizeof(D3DLIGHT7));
261 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
262 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
263 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
264 "light data doesn't match expected default values\n" );
267 /* Disable one of the light that have been previously enabled. */
268 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
269 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
271 /* Try to retrieve the enable status of some lights */
272 /* Light 20 is supposed to be disabled */
273 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
274 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
275 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
277 /* Light 10 is supposed to be enabled */
278 bEnabled = FALSE;
279 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
280 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
281 ok(bEnabled, "GetLightEnable says the light is disabled\n");
283 /* Light 80 has not been set */
284 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
285 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
287 /* Light 23 has not been set */
288 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
289 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
291 /* Set some lights with invalid parameters */
292 memset(&light, 0, sizeof(D3DLIGHT7));
293 light.dltType = 0;
294 U1(light.dcvDiffuse).r = 1.f;
295 U2(light.dcvDiffuse).g = 1.f;
296 U3(light.dcvDiffuse).b = 1.f;
297 U3(light.dvDirection).z = 1.f;
298 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
299 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
301 memset(&light, 0, sizeof(D3DLIGHT7));
302 light.dltType = 12345;
303 U1(light.dcvDiffuse).r = 1.f;
304 U2(light.dcvDiffuse).g = 1.f;
305 U3(light.dcvDiffuse).b = 1.f;
306 U3(light.dvDirection).z = 1.f;
307 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
308 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
310 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
311 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
313 memset(&light, 0, sizeof(D3DLIGHT7));
314 light.dltType = D3DLIGHT_SPOT;
315 U1(light.dcvDiffuse).r = 1.f;
316 U2(light.dcvDiffuse).g = 1.f;
317 U3(light.dcvDiffuse).b = 1.f;
318 U3(light.dvDirection).z = 1.f;
320 light.dvAttenuation0 = -one / zero; /* -INFINITY */
321 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
322 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
324 light.dvAttenuation0 = -1.0;
325 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
326 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
328 light.dvAttenuation0 = 0.0;
329 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
330 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
332 light.dvAttenuation0 = 1.0;
333 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
334 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
336 light.dvAttenuation0 = one / zero; /* +INFINITY */
337 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
338 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
340 light.dvAttenuation0 = zero / zero; /* NaN */
341 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
342 ok(rc==D3D_OK ||
343 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
345 /* Directional light ignores attenuation */
346 light.dltType = D3DLIGHT_DIRECTIONAL;
347 light.dvAttenuation0 = -1.0;
348 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
349 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
351 memset(&mat, 0, sizeof(mat));
352 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
353 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
355 U4(mat).power = 129.0;
356 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
357 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
358 memset(&mat, 0, sizeof(mat));
359 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
360 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
361 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
363 U4(mat).power = -1.0;
364 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
365 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
366 memset(&mat, 0, sizeof(mat));
367 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
368 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
369 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
371 memset(&caps, 0, sizeof(caps));
372 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
373 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
375 if ( caps.dwMaxActiveLights == (DWORD) -1) {
376 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
377 skip("T&L not supported\n");
378 return;
381 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
382 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
383 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
384 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
385 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
386 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
389 /* TODO: Test the rendering results in this situation */
390 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
391 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
392 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
393 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
394 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
395 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
396 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
398 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
399 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
400 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
404 static void ProcessVerticesTest(void)
406 D3DVERTEXBUFFERDESC desc;
407 HRESULT rc;
408 VERTEX *in;
409 TVERTEX *out;
410 VERTEX *out2;
411 D3DVIEWPORT7 vp;
412 D3DMATRIX view = { 2.0, 0.0, 0.0, 0.0,
413 0.0, -1.0, 0.0, 0.0,
414 0.0, 0.0, 1.0, 0.0,
415 0.0, 0.0, 0.0, 3.0 };
417 D3DMATRIX world = { 0.0, 1.0, 0.0, 0.0,
418 1.0, 0.0, 0.0, 0.0,
419 0.0, 0.0, 0.0, 1.0,
420 0.0, 1.0, 1.0, 1.0 };
422 D3DMATRIX proj = { 1.0, 0.0, 0.0, 1.0,
423 0.0, 1.0, 1.0, 0.0,
424 0.0, 1.0, 1.0, 0.0,
425 1.0, 0.0, 0.0, 1.0 };
426 /* Create some vertex buffers */
428 memset(&desc, 0, sizeof(desc));
429 desc.dwSize = sizeof(desc);
430 desc.dwCaps = 0;
431 desc.dwFVF = D3DFVF_XYZ;
432 desc.dwNumVertices = 16;
433 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
434 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
435 if (!lpVBufSrc)
437 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
438 goto out;
441 memset(&desc, 0, sizeof(desc));
442 desc.dwSize = sizeof(desc);
443 desc.dwCaps = 0;
444 desc.dwFVF = D3DFVF_XYZRHW;
445 desc.dwNumVertices = 16;
446 /* Msdn says that the last parameter must be 0 - check that */
447 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest1, 4);
448 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
449 if (!lpVBufDest1)
451 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
452 goto out;
455 memset(&desc, 0, sizeof(desc));
456 desc.dwSize = sizeof(desc);
457 desc.dwCaps = 0;
458 desc.dwFVF = D3DFVF_XYZ;
459 desc.dwNumVertices = 16;
460 /* Msdn says that the last parameter must be 0 - check that */
461 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest2, 12345678);
462 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
463 if (!lpVBufDest2)
465 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
466 goto out;
469 rc = IDirect3DVertexBuffer7_Lock(lpVBufSrc, 0, (void **) &in, NULL);
470 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
471 if(!in) goto out;
473 /* Check basic transformation */
475 in[0].x = 0.0;
476 in[0].y = 0.0;
477 in[0].z = 0.0;
479 in[1].x = 1.0;
480 in[1].y = 1.0;
481 in[1].z = 1.0;
483 in[2].x = -1.0;
484 in[2].y = -1.0;
485 in[2].z = 0.5;
487 in[3].x = 0.5;
488 in[3].y = -0.5;
489 in[3].z = 0.25;
490 rc = IDirect3DVertexBuffer7_Unlock(lpVBufSrc);
491 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
493 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
494 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
496 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest2, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
497 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
499 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
500 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
501 if(!out) goto out;
503 /* Check the results */
504 ok( comparefloat(out[0].x, 128.0 ) &&
505 comparefloat(out[0].y, 128.0 ) &&
506 comparefloat(out[0].z, 0.0 ) &&
507 comparefloat(out[0].rhw, 1.0 ),
508 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
510 ok( comparefloat(out[1].x, 256.0 ) &&
511 comparefloat(out[1].y, 0.0 ) &&
512 comparefloat(out[1].z, 1.0 ) &&
513 comparefloat(out[1].rhw, 1.0 ),
514 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
516 ok( comparefloat(out[2].x, 0.0 ) &&
517 comparefloat(out[2].y, 256.0 ) &&
518 comparefloat(out[2].z, 0.5 ) &&
519 comparefloat(out[2].rhw, 1.0 ),
520 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
522 ok( comparefloat(out[3].x, 192.0 ) &&
523 comparefloat(out[3].y, 192.0 ) &&
524 comparefloat(out[3].z, 0.25 ) &&
525 comparefloat(out[3].rhw, 1.0 ),
526 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
528 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
529 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
530 out = NULL;
532 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest2, 0, (void **) &out2, NULL);
533 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
534 if(!out2) goto out;
535 /* Small thing without much practical meaning, but I stumbled upon it,
536 * so let's check for it: If the output vertex buffer has to RHW value,
537 * The RHW value of the last vertex is written into the next vertex
539 ok( comparefloat(out2[4].x, 1.0 ) &&
540 comparefloat(out2[4].y, 0.0 ) &&
541 comparefloat(out2[4].z, 0.0 ),
542 "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z);
544 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest2);
545 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
546 out = NULL;
548 /* Try a more complicated viewport, same vertices */
549 memset(&vp, 0, sizeof(vp));
550 vp.dwX = 10;
551 vp.dwY = 5;
552 vp.dwWidth = 246;
553 vp.dwHeight = 130;
554 vp.dvMinZ = -2.0;
555 vp.dvMaxZ = 4.0;
556 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
557 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed with rc=%x\n", rc);
559 /* Process again */
560 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
561 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
563 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
564 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
565 if(!out) goto out;
567 /* Check the results */
568 ok( comparefloat(out[0].x, 133.0 ) &&
569 comparefloat(out[0].y, 70.0 ) &&
570 comparefloat(out[0].z, -2.0 ) &&
571 comparefloat(out[0].rhw, 1.0 ),
572 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
574 ok( comparefloat(out[1].x, 256.0 ) &&
575 comparefloat(out[1].y, 5.0 ) &&
576 comparefloat(out[1].z, 4.0 ) &&
577 comparefloat(out[1].rhw, 1.0 ),
578 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
580 ok( comparefloat(out[2].x, 10.0 ) &&
581 comparefloat(out[2].y, 135.0 ) &&
582 comparefloat(out[2].z, 1.0 ) &&
583 comparefloat(out[2].rhw, 1.0 ),
584 "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
586 ok( comparefloat(out[3].x, 194.5 ) &&
587 comparefloat(out[3].y, 102.5 ) &&
588 comparefloat(out[3].z, -0.5 ) &&
589 comparefloat(out[3].rhw, 1.0 ),
590 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
592 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
593 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
594 out = NULL;
596 /* Play with some matrices. */
598 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW, &view);
599 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
601 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
602 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
604 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
605 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
607 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
608 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
610 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
611 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
612 if(!out) goto out;
614 /* Keep the viewport simpler, otherwise we get bad numbers to compare */
615 vp.dwX = 0;
616 vp.dwY = 0;
617 vp.dwWidth = 100;
618 vp.dwHeight = 100;
619 vp.dvMinZ = 1.0;
620 vp.dvMaxZ = 0.0;
621 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
622 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed\n");
624 /* Check the results */
625 ok( comparefloat(out[0].x, 256.0 ) && /* X coordinate is cut at the surface edges */
626 comparefloat(out[0].y, 70.0 ) &&
627 comparefloat(out[0].z, -2.0 ) &&
628 comparefloat(out[0].rhw, (1.0 / 3.0)),
629 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
631 ok( comparefloat(out[1].x, 256.0 ) &&
632 comparefloat(out[1].y, 78.125000 ) &&
633 comparefloat(out[1].z, -2.750000 ) &&
634 comparefloat(out[1].rhw, 0.125000 ),
635 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
637 ok( comparefloat(out[2].x, 256.0 ) &&
638 comparefloat(out[2].y, 44.000000 ) &&
639 comparefloat(out[2].z, 0.400000 ) &&
640 comparefloat(out[2].rhw, 0.400000 ),
641 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
643 ok( comparefloat(out[3].x, 256.0 ) &&
644 comparefloat(out[3].y, 81.818184 ) &&
645 comparefloat(out[3].z, -3.090909 ) &&
646 comparefloat(out[3].rhw, 0.363636 ),
647 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
649 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
650 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
651 out = NULL;
653 out:
654 IDirect3DVertexBuffer7_Release(lpVBufSrc);
655 IDirect3DVertexBuffer7_Release(lpVBufDest1);
656 IDirect3DVertexBuffer7_Release(lpVBufDest2);
659 static void StateTest( void )
661 HRESULT rc;
663 /* The msdn says its undocumented, does it return an error too? */
664 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
665 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
666 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
667 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
671 static void SceneTest(void)
673 HRESULT hr;
675 /* Test an EndScene without beginscene. Should return an error */
676 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
677 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
679 /* Test a normal BeginScene / EndScene pair, this should work */
680 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
681 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
682 if(SUCCEEDED(hr))
684 DDBLTFX fx;
685 memset(&fx, 0, sizeof(fx));
686 fx.dwSize = sizeof(fx);
688 if(lpDDSdepth) {
689 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
690 ok(hr == D3D_OK, "Depthfill failed in a BeginScene / EndScene pair\n");
691 } else {
692 skip("Depth stencil creation failed at startup, skipping\n");
694 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
695 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
698 /* Test another EndScene without having begun a new scene. Should return an error */
699 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
700 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
702 /* Two nested BeginScene and EndScene calls */
703 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
704 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
705 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
706 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
707 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
708 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
709 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
710 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
712 /* TODO: Verify that blitting works in the same way as in d3d9 */
715 static void LimitTest(void)
717 IDirectDrawSurface7 *pTexture = NULL;
718 HRESULT hr;
719 int i;
720 DDSURFACEDESC2 ddsd;
722 memset(&ddsd, 0, sizeof(ddsd));
723 ddsd.dwSize = sizeof(ddsd);
724 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
725 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
726 ddsd.dwWidth = 16;
727 ddsd.dwHeight = 16;
728 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
729 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
730 if(!pTexture) return;
732 for(i = 0; i < 8; i++) {
733 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
734 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
735 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
736 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
737 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
738 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
741 IDirectDrawSurface7_Release(pTexture);
744 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
746 UINT ver = *((UINT *) ctx);
747 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
749 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
750 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
751 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
752 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
753 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
754 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
755 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
756 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
758 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
759 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
760 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
761 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
762 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
763 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
764 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
765 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
767 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
769 /* pow2 is hardware dependent */
771 ok(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
772 "HAL Device %d hal line caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
773 ok(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
774 "HAL Device %d hal tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
775 ok((hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
776 "HAL Device %d hel line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
777 ok((hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
778 "HAL Device %d hel tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
780 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
782 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
783 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
784 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
785 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
786 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
787 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
788 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
789 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
791 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
792 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
793 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
794 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
795 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
796 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
797 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
798 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
800 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
802 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
803 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
804 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
805 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
806 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
807 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
808 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
809 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
811 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
812 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
813 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
814 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
815 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
816 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
817 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
818 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
820 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
822 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
823 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
824 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
825 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
826 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
827 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
828 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
829 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
831 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
832 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
833 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
834 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
835 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
836 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
837 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
838 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
840 else
842 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
843 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
844 else trace("hal line does NOT have pow2 set\n");
845 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
846 else trace("hal tri does NOT have pow2 set\n");
847 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
848 else trace("hel line does NOT have pow2 set\n");
849 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
850 else trace("hel tri does NOT have pow2 set\n");
852 return DDENUMRET_OK;
855 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
857 D3D7ETest *d3d7et = Context;
858 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
859 d3d7et->rgb++;
860 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
861 d3d7et->hal++;
862 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
863 d3d7et->tnlhal++;
864 else
865 d3d7et->unk++;
867 d3d7et->total++;
869 return DDENUMRET_OK;
873 /* Check the deviceGUID of devices enumerated by
874 IDirect3D7_EnumDevices. */
875 static void D3D7EnumTest(void)
877 D3D7ETest d3d7et;
879 if (!lpD3D) {
880 skip("No Direct3D7 interface.\n");
881 return;
884 memset(&d3d7et, 0, sizeof(d3d7et));
885 IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
887 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
888 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
890 /* We make two additional assumptions. */
891 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
893 if(d3d7et.tnlhal)
894 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
897 static void CapsTest(void)
899 IDirect3D3 *d3d3;
900 IDirect3D3 *d3d2;
901 IDirectDraw *dd1;
902 HRESULT hr;
903 UINT ver;
905 hr = DirectDrawCreate(NULL, &dd1, NULL);
906 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
907 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
908 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
909 ver = 3;
910 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
912 IDirect3D3_Release(d3d3);
913 IDirectDraw_Release(dd1);
915 hr = DirectDrawCreate(NULL, &dd1, NULL);
916 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
917 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
918 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
919 ver = 2;
920 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
922 IDirect3D2_Release(d3d2);
923 IDirectDraw_Release(dd1);
926 struct v_in {
927 float x, y, z;
929 struct v_out {
930 float x, y, z, rhw;
933 static BOOL D3D1_createObjects(void)
935 HRESULT hr;
936 DDSURFACEDESC ddsd;
937 D3DEXECUTEBUFFERDESC desc;
938 D3DVIEWPORT vp_data;
940 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
941 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
942 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
943 if (!DirectDraw1) {
944 return FALSE;
947 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
948 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
950 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
951 if (hr == E_NOINTERFACE) return FALSE;
952 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
953 if (!Direct3D1) {
954 return FALSE;
957 memset(&ddsd, 0, sizeof(ddsd));
958 ddsd.dwSize = sizeof(ddsd);
959 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
960 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
961 ddsd.dwWidth = 256;
962 ddsd.dwHeight = 256;
963 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
964 if (!Surface1) {
965 skip("DDSCAPS_3DDEVICE surface not available\n");
966 return FALSE;
969 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
970 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
971 if(!Direct3DDevice1) {
972 return FALSE;
975 memset(&desc, 0, sizeof(desc));
976 desc.dwSize = sizeof(desc);
977 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
978 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
979 desc.dwBufferSize = 128;
980 desc.lpData = NULL;
981 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
982 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
983 if(!ExecuteBuffer) {
984 return FALSE;
987 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
988 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
989 if(!Viewport) {
990 return FALSE;
993 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
994 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
996 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
997 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
998 vp_data.dwSize = sizeof(vp_data);
999 vp_data.dwX = 0;
1000 vp_data.dwY = 0;
1001 vp_data.dwWidth = 256;
1002 vp_data.dwHeight = 256;
1003 vp_data.dvScaleX = 1;
1004 vp_data.dvScaleY = 1;
1005 vp_data.dvMaxX = 256;
1006 vp_data.dvMaxY = 256;
1007 vp_data.dvMinZ = 0;
1008 vp_data.dvMaxZ = 1;
1009 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1010 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1012 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1013 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1014 if (!Light)
1015 return FALSE;
1017 return TRUE;
1020 static void D3D1_releaseObjects(void)
1022 if (Light) IDirect3DLight_Release(Light);
1023 if (Viewport) IDirect3DViewport_Release(Viewport);
1024 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1025 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1026 if (Surface1) IDirectDrawSurface_Release(Surface1);
1027 if (Direct3D1) IDirect3D_Release(Direct3D1);
1028 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1031 #define SET_VP_DATA(vp_data) \
1032 vp_data.dwSize = sizeof(vp_data); \
1033 vp_data.dwX = 0; \
1034 vp_data.dwY = 0; \
1035 vp_data.dwWidth = 256; \
1036 vp_data.dwHeight = 256; \
1037 vp_data.dvMaxX = 256; \
1038 vp_data.dvMaxY = 256; \
1039 vp_data.dvScaleX = 5; \
1040 vp_data.dvScaleY = 5; \
1041 vp_data.dvMinZ = -25; \
1042 vp_data.dvMaxZ = 60;
1044 static void Direct3D1Test(void)
1046 HRESULT hr;
1047 D3DEXECUTEBUFFERDESC desc;
1048 D3DVIEWPORT vp_data;
1049 D3DINSTRUCTION *instr;
1050 D3DBRANCH *branch;
1051 IDirect3D *Direct3D_alt;
1052 IDirect3DLight *d3dlight;
1053 ULONG refcount;
1054 unsigned int idx = 0;
1055 static struct v_in testverts[] = {
1056 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1057 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1059 static struct v_in cliptest[] = {
1060 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1061 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1063 static struct v_in offscreentest[] = {
1064 {128.1, 0.0, 0.0},
1066 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1067 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1068 D3DTRANSFORMDATA transformdata;
1069 DWORD i = FALSE;
1071 /* Interface consistency check. */
1072 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1073 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1074 if (hr == D3D_OK)
1075 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1077 memset(&desc, 0, sizeof(desc));
1078 desc.dwSize = sizeof(desc);
1079 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1080 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1082 memset(desc.lpData, 0, 128);
1083 instr = desc.lpData;
1084 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1085 instr[idx].bSize = sizeof(*branch);
1086 instr[idx].wCount = 1;
1087 idx++;
1088 branch = (D3DBRANCH *) &instr[idx];
1089 branch->dwMask = 0x0;
1090 branch->dwValue = 1;
1091 branch->bNegate = TRUE;
1092 branch->dwOffset = 0;
1093 idx += (sizeof(*branch) / sizeof(*instr));
1094 instr[idx].bOpcode = D3DOP_EXIT;
1095 instr[idx].bSize = 0;
1096 instr[idx].wCount = 0;
1097 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1098 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1100 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1101 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1103 memset(&desc, 0, sizeof(desc));
1104 desc.dwSize = sizeof(desc);
1106 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1107 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1109 memset(desc.lpData, 0, 128);
1110 instr = desc.lpData;
1111 idx = 0;
1112 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1113 instr[idx].bSize = sizeof(*branch);
1114 instr[idx].wCount = 1;
1115 idx++;
1116 branch = (D3DBRANCH *) &instr[idx];
1117 branch->dwMask = 0x0;
1118 branch->dwValue = 1;
1119 branch->bNegate = TRUE;
1120 branch->dwOffset = 64;
1121 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1122 instr[0].bOpcode = D3DOP_EXIT;
1123 instr[0].bSize = 0;
1124 instr[0].wCount = 0;
1125 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1126 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1128 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1129 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1131 /* Test rendering 0 triangles */
1132 memset(&desc, 0, sizeof(desc));
1133 desc.dwSize = sizeof(desc);
1135 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1136 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1138 memset(desc.lpData, 0, 128);
1139 instr = desc.lpData;
1140 idx = 0;
1142 instr->bOpcode = D3DOP_TRIANGLE;
1143 instr->bSize = sizeof(D3DOP_TRIANGLE);
1144 instr->wCount = 0;
1145 instr++;
1146 instr->bOpcode = D3DOP_EXIT;
1147 instr->bSize = 0;
1148 instr->wCount = 0;
1149 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1150 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1152 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1153 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1155 memset(&transformdata, 0, sizeof(transformdata));
1156 transformdata.dwSize = sizeof(transformdata);
1157 transformdata.lpIn = testverts;
1158 transformdata.dwInSize = sizeof(testverts[0]);
1159 transformdata.lpOut = out;
1160 transformdata.dwOutSize = sizeof(out[0]);
1162 transformdata.lpHOut = NULL;
1163 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1164 &transformdata, D3DTRANSFORM_UNCLIPPED,
1165 &i);
1166 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1168 transformdata.lpHOut = outH;
1169 memset(outH, 0xcc, sizeof(outH));
1170 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1171 &transformdata, D3DTRANSFORM_UNCLIPPED,
1172 &i);
1173 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1174 ok(i == 0, "Offscreen is %d\n", i);
1176 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1177 static const struct v_out cmp[] = {
1178 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1179 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1182 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1183 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1184 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1185 out[i].x, out[i].y, out[i].z, out[i].rhw,
1186 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1188 for(i = 0; i < sizeof(outH); i++) {
1189 if(((unsigned char *) outH)[i] != 0xcc) {
1190 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1191 break;
1195 SET_VP_DATA(vp_data);
1196 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1197 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1198 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1199 &transformdata, D3DTRANSFORM_UNCLIPPED,
1200 &i);
1201 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1202 ok(i == 0, "Offscreen is %d\n", i);
1204 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1205 static const struct v_out cmp[] = {
1206 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1207 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1209 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1210 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1211 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1212 out[i].x, out[i].y, out[i].z, out[i].rhw,
1213 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1216 SET_VP_DATA(vp_data);
1217 vp_data.dwX = 10;
1218 vp_data.dwY = 20;
1219 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1220 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1221 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1222 &transformdata, D3DTRANSFORM_UNCLIPPED,
1223 &i);
1224 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1225 ok(i == 0, "Offscreen is %d\n", i);
1226 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1227 static const struct v_out cmp[] = {
1228 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1229 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1231 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1232 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1233 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1234 out[i].x, out[i].y, out[i].z, out[i].rhw,
1235 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1238 memset(out, 0xcc, sizeof(out));
1239 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1240 &transformdata, D3DTRANSFORM_CLIPPED,
1241 &i);
1242 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1243 ok(i == 0, "Offscreen is %d\n", i);
1244 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1245 static const D3DHVERTEX cmpH[] = {
1246 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1247 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1248 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1250 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1251 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1252 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1253 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1254 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1256 /* No scheme has been found behind those return values. It seems to be
1257 * whatever data windows has when throwing the vertex away. Modify the
1258 * input test vertices to test this more. Depending on the input data
1259 * it can happen that the z coord gets written into y, or similar things
1261 if(0)
1263 static const struct v_out cmp[] = {
1264 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1265 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1267 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1268 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1269 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1270 out[i].x, out[i].y, out[i].z, out[i].rhw,
1271 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1274 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1275 ok(((DWORD *) out)[i] != 0xcccccccc,
1276 "Regular output DWORD %d remained untouched\n", i);
1279 transformdata.lpIn = cliptest;
1280 transformdata.dwInSize = sizeof(cliptest[0]);
1281 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1282 &transformdata, D3DTRANSFORM_CLIPPED,
1283 &i);
1284 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1285 ok(i == 0, "Offscreen is %d\n", i);
1286 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1287 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1291 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1292 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1294 ok(Flags[i] == outH[i].dwFlags,
1295 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1296 outH[i].dwFlags, Flags[i]);
1299 SET_VP_DATA(vp_data);
1300 vp_data.dwWidth = 10;
1301 vp_data.dwHeight = 1000;
1302 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1303 i = 10;
1304 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1305 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1306 &transformdata, D3DTRANSFORM_CLIPPED,
1307 &i);
1308 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1309 ok(i == 0, "Offscreen is %d\n", i);
1310 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1311 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1313 D3DCLIP_RIGHT,
1314 D3DCLIP_LEFT,
1315 D3DCLIP_RIGHT | D3DCLIP_BACK,
1316 D3DCLIP_LEFT | D3DCLIP_FRONT,
1318 ok(Flags[i] == outH[i].dwFlags,
1319 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1320 outH[i].dwFlags, Flags[i]);
1323 SET_VP_DATA(vp_data);
1324 vp_data.dwWidth = 256;
1325 vp_data.dwHeight = 256;
1326 vp_data.dvScaleX = 1;
1327 vp_data.dvScaleY = 1;
1328 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1329 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1330 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1331 &transformdata, D3DTRANSFORM_CLIPPED,
1332 &i);
1333 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1334 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1335 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1336 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1340 D3DCLIP_BACK,
1341 D3DCLIP_FRONT,
1343 ok(Flags[i] == outH[i].dwFlags,
1344 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1345 outH[i].dwFlags, Flags[i]);
1348 /* Finally try to figure out how the DWORD dwOffscreen works.
1349 * Apparently no vertex is offscreen with clipping off,
1350 * and with clipping on the offscreen flag is set if only one vertex
1351 * is transformed, and this vertex is offscreen.
1353 SET_VP_DATA(vp_data);
1354 vp_data.dwWidth = 5;
1355 vp_data.dwHeight = 5;
1356 vp_data.dvScaleX = 10000;
1357 vp_data.dvScaleY = 10000;
1358 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1359 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1360 transformdata.lpIn = cliptest;
1361 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1362 &transformdata, D3DTRANSFORM_UNCLIPPED,
1363 &i);
1364 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1365 ok(i == 0, "Offscreen is %d\n", i);
1366 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1367 &transformdata, D3DTRANSFORM_CLIPPED,
1368 &i);
1369 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1370 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1371 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1372 &transformdata, D3DTRANSFORM_CLIPPED,
1373 &i);
1374 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1375 ok(i == 0, "Offscreen is %d\n", i);
1376 transformdata.lpIn = cliptest + 1;
1377 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1378 &transformdata, D3DTRANSFORM_CLIPPED,
1379 &i);
1380 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1381 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1383 transformdata.lpIn = offscreentest;
1384 transformdata.dwInSize = sizeof(offscreentest[0]);
1385 SET_VP_DATA(vp_data);
1386 vp_data.dwWidth = 257;
1387 vp_data.dwHeight = 257;
1388 vp_data.dvScaleX = 1;
1389 vp_data.dvScaleY = 1;
1390 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1391 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1392 i = 12345;
1393 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1394 &transformdata, D3DTRANSFORM_CLIPPED,
1395 &i);
1396 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1397 ok(i == 0, "Offscreen is %d\n", i);
1398 vp_data.dwWidth = 256;
1399 vp_data.dwHeight = 256;
1400 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1401 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1402 i = 12345;
1403 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1404 &transformdata, D3DTRANSFORM_CLIPPED,
1405 &i);
1406 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1407 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1409 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1410 &transformdata, 0,
1411 &i);
1412 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1414 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1415 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1417 hr = IDirect3DViewport_AddLight(Viewport, Light);
1418 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1419 refcount = getRefcount((IUnknown*) Light);
1420 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1422 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1423 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1424 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1425 refcount = getRefcount((IUnknown*) Light);
1426 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1428 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1429 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1430 refcount = getRefcount((IUnknown*) Light);
1431 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1433 IDirect3DLight_Release(Light);
1436 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1438 int i;
1440 for (i = 0; i < 256; i++) {
1441 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1442 table1[i].peBlue != table2[i].peBlue) return FALSE;
1445 return TRUE;
1448 /* test palette handling in IDirect3DTexture_Load */
1449 static void TextureLoadTest(void)
1451 IDirectDrawSurface *TexSurface = NULL;
1452 IDirect3DTexture *Texture = NULL;
1453 IDirectDrawSurface *TexSurface2 = NULL;
1454 IDirect3DTexture *Texture2 = NULL;
1455 IDirectDrawPalette *palette = NULL;
1456 IDirectDrawPalette *palette2 = NULL;
1457 IDirectDrawPalette *palette_tmp = NULL;
1458 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1459 HRESULT hr;
1460 DDSURFACEDESC ddsd;
1461 int i;
1463 memset (&ddsd, 0, sizeof (ddsd));
1464 ddsd.dwSize = sizeof (ddsd);
1465 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1466 ddsd.dwHeight = 128;
1467 ddsd.dwWidth = 128;
1468 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1469 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1470 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1471 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1473 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1474 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1475 if (FAILED(hr)) {
1476 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1477 goto cleanup;
1480 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1481 (void *)&Texture);
1482 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1483 if (FAILED(hr)) {
1484 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1485 goto cleanup;
1488 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1489 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1490 if (FAILED(hr)) {
1491 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1492 goto cleanup;
1495 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1496 (void *)&Texture2);
1497 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1498 if (FAILED(hr)) {
1499 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1500 goto cleanup;
1503 /* test load of Texture to Texture */
1504 hr = IDirect3DTexture_Load(Texture, Texture);
1505 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1507 /* test Load when both textures have no palette */
1508 hr = IDirect3DTexture_Load(Texture2, Texture);
1509 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1511 for (i = 0; i < 256; i++) {
1512 table1[i].peRed = i;
1513 table1[i].peGreen = i;
1514 table1[i].peBlue = i;
1515 table1[i].peFlags = 0;
1518 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1519 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1520 if (FAILED(hr)) {
1521 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1522 goto cleanup;
1525 /* test Load when source texture has palette and destination has no palette */
1526 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1527 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1528 hr = IDirect3DTexture_Load(Texture2, Texture);
1529 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1531 for (i = 0; i < 256; i++) {
1532 table2[i].peRed = 255 - i;
1533 table2[i].peGreen = 255 - i;
1534 table2[i].peBlue = 255 - i;
1535 table2[i].peFlags = 0;
1538 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1539 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1540 if (FAILED(hr)) {
1541 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1542 goto cleanup;
1545 /* test Load when source has no palette and destination has a palette */
1546 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1547 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1548 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1549 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1550 hr = IDirect3DTexture_Load(Texture2, Texture);
1551 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1552 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1553 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1554 if (!palette_tmp) {
1555 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1556 goto cleanup;
1557 } else {
1558 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1559 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1560 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1561 IDirectDrawPalette_Release(palette_tmp);
1564 /* test Load when both textures have palettes */
1565 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1566 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1567 hr = IDirect3DTexture_Load(Texture2, Texture);
1568 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1569 hr = IDirect3DTexture_Load(Texture2, Texture);
1570 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1571 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1572 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1573 if (!palette_tmp) {
1574 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1575 goto cleanup;
1576 } else {
1577 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1578 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1579 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1580 IDirectDrawPalette_Release(palette_tmp);
1583 cleanup:
1585 if (palette) IDirectDrawPalette_Release(palette);
1586 if (palette2) IDirectDrawPalette_Release(palette2);
1587 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1588 if (Texture) IDirect3DTexture_Release(Texture);
1589 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1590 if (Texture2) IDirect3DTexture_Release(Texture2);
1593 static void VertexBufferDescTest(void)
1595 HRESULT rc;
1596 D3DVERTEXBUFFERDESC desc;
1597 union mem_t
1599 D3DVERTEXBUFFERDESC desc2;
1600 unsigned char buffer[512];
1601 } mem;
1603 memset(&desc, 0, sizeof(desc));
1604 desc.dwSize = sizeof(desc);
1605 desc.dwCaps = 0;
1606 desc.dwFVF = D3DFVF_XYZ;
1607 desc.dwNumVertices = 1;
1608 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1609 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1610 if (!lpVBufSrc)
1612 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1613 goto out;
1616 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1617 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1618 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1619 if(rc != D3D_OK)
1620 skip("GetVertexBuffer Failed!\n");
1621 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1622 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1623 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1624 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1625 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1627 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1628 mem.desc2.dwSize = 0;
1629 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1630 if(rc != D3D_OK)
1631 skip("GetVertexBuffer Failed!\n");
1632 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1633 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1634 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1635 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1636 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1638 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1639 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1640 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1641 if(rc != D3D_OK)
1642 skip("GetVertexBuffer Failed!\n");
1643 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1644 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1645 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1646 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1647 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1649 out:
1650 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1653 static void D3D7_OldRenderStateTest(void)
1655 HRESULT rc;
1656 DWORD val;
1658 /* Test reaction to some deprecated states in D3D7.
1660 * IDirect3DDevice7 in Wine currently relays such states to wined3d where they are do-nothing and return 0, instead
1661 * of INVALIDPARAMS. Unless an app is found which cares this is probably ok. What this test shows is that these states
1662 * need not to be handled in D3D7.
1664 todo_wine {
1665 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1666 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %08x\n", rc);
1668 rc = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1669 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %08x\n", rc);
1671 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1672 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %08x\n", rc);
1674 rc = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1675 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %08x\n", rc);
1679 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1680 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1682 static void DeviceLoadTest(void)
1684 DDSURFACEDESC2 ddsd;
1685 IDirectDrawSurface7 *texture_levels[2][8];
1686 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1687 DWORD flags;
1688 HRESULT hr;
1689 DDBLTFX ddbltfx;
1690 RECT loadrect;
1691 POINT loadpoint;
1692 int i, i1, i2;
1693 unsigned diff_count = 0, diff_count2 = 0;
1694 unsigned x, y;
1695 BOOL load_mip_subset_broken = FALSE;
1696 IDirectDrawPalette *palettes[5];
1697 PALETTEENTRY table1[256];
1698 DDCOLORKEY ddckey;
1699 D3DDEVICEDESC7 d3dcaps;
1701 /* Test loading of texture subrectangle with a mipmap surface. */
1702 memset(texture_levels, 0, sizeof(texture_levels));
1703 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1704 memset(palettes, 0, sizeof(palettes));
1706 for (i = 0; i < 2; i++)
1708 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1709 ddsd.dwSize = sizeof(ddsd);
1710 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1711 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1712 ddsd.dwWidth = 128;
1713 ddsd.dwHeight = 128;
1714 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1715 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1716 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1717 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1718 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1719 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1720 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1721 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1722 if (FAILED(hr)) goto out;
1724 /* Check the number of created mipmaps */
1725 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1726 ddsd.dwSize = sizeof(ddsd);
1727 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1728 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1729 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1730 if (U2(ddsd).dwMipMapCount != 8) goto out;
1732 for (i1 = 1; i1 < 8; i1++)
1734 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1735 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1736 if (FAILED(hr)) goto out;
1740 for (i1 = 0; i1 < 8; i1++)
1742 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1743 ddsd.dwSize = sizeof(ddsd);
1744 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1745 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1746 if (FAILED(hr)) goto out;
1748 for (y = 0 ; y < ddsd.dwHeight; y++)
1750 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1752 for (x = 0; x < ddsd.dwWidth; x++)
1754 /* x stored in green component, y in blue. */
1755 DWORD color = 0xff0000 | (x << 8) | y;
1756 *textureRow++ = color;
1760 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1761 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1764 for (i1 = 0; i1 < 8; i1++)
1766 memset(&ddbltfx, 0, sizeof(ddbltfx));
1767 ddbltfx.dwSize = sizeof(ddbltfx);
1768 U5(ddbltfx).dwFillColor = 0;
1769 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1770 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1773 /* First test some broken coordinates. */
1774 loadpoint.x = loadpoint.y = 0;
1775 loadrect.left = 0;
1776 loadrect.top = 0;
1777 loadrect.right = 0;
1778 loadrect.bottom = 0;
1779 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1780 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1782 loadpoint.x = loadpoint.y = 50;
1783 loadrect.left = 0;
1784 loadrect.top = 0;
1785 loadrect.right = 100;
1786 loadrect.bottom = 100;
1787 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1788 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1790 /* Test actual loading. */
1791 loadpoint.x = loadpoint.y = 31;
1792 loadrect.left = 30;
1793 loadrect.top = 20;
1794 loadrect.right = 93;
1795 loadrect.bottom = 52;
1797 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1798 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1800 for (i1 = 0; i1 < 8; i1++)
1802 diff_count = 0;
1803 diff_count2 = 0;
1805 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1806 ddsd.dwSize = sizeof(ddsd);
1807 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1808 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1809 if (FAILED(hr)) goto out;
1811 for (y = 0 ; y < ddsd.dwHeight; y++)
1813 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1815 for (x = 0; x < ddsd.dwWidth; x++)
1817 DWORD color = *textureRow++;
1819 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1820 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1822 if (color & 0xffffff) diff_count++;
1824 else
1826 DWORD r = (color & 0xff0000) >> 16;
1827 DWORD g = (color & 0xff00) >> 8;
1828 DWORD b = (color & 0xff);
1830 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1833 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1834 technically be correct as it's not precisely defined by docs. */
1835 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1836 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1838 if (color & 0xffffff) diff_count2++;
1840 else
1842 DWORD r = (color & 0xff0000) >> 16;
1843 DWORD g = (color & 0xff00) >> 8;
1844 DWORD b = (color & 0xff);
1846 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1847 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1852 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
1853 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1855 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
1856 MIN(diff_count, diff_count2), i1);
1858 loadpoint.x /= 2;
1859 loadpoint.y /= 2;
1860 loadrect.top /= 2;
1861 loadrect.left /= 2;
1862 loadrect.right = (loadrect.right + 1) / 2;
1863 loadrect.bottom = (loadrect.bottom + 1) / 2;
1866 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
1867 * qemu Win98 / directx7 / RGB software rasterizer):
1868 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
1869 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
1872 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
1873 for (i = 0; i < 2; i++)
1875 for (i1 = 7; i1 >= 0; i1--)
1877 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
1880 memset(texture_levels, 0, sizeof(texture_levels));
1882 /* Test texture size mismatch. */
1883 for (i = 0; i < 2; i++)
1885 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1886 ddsd.dwSize = sizeof(ddsd);
1887 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1888 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1889 ddsd.dwWidth = i ? 256 : 128;
1890 ddsd.dwHeight = 128;
1891 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1892 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1893 if (FAILED(hr)) goto out;
1896 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
1897 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1899 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
1900 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1902 IDirectDrawSurface7_Release(texture_levels[0][0]);
1903 IDirectDrawSurface7_Release(texture_levels[1][0]);
1904 memset(texture_levels, 0, sizeof(texture_levels));
1906 memset(&d3dcaps, 0, sizeof(d3dcaps));
1907 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
1908 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
1910 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
1912 skip("No cubemap support\n");
1914 else
1916 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
1917 for (i = 0; i < 2; i++)
1919 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1920 ddsd.dwSize = sizeof(ddsd);
1921 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1922 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1923 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1924 ddsd.dwWidth = 128;
1925 ddsd.dwHeight = 128;
1926 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1927 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1928 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1929 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1930 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1931 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1932 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
1933 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1934 if (FAILED(hr)) goto out;
1936 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
1937 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
1939 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1940 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
1941 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
1942 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1943 if (FAILED(hr)) goto out;
1946 for (i1 = 0; i1 < 6; i1++)
1948 /* Check the number of created mipmaps */
1949 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1950 ddsd.dwSize = sizeof(ddsd);
1951 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
1952 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1953 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1954 if (U2(ddsd).dwMipMapCount != 8) goto out;
1956 for (i2 = 1; i2 < 8; i2++)
1958 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
1959 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
1960 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
1961 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1962 if (FAILED(hr)) goto out;
1967 for (i = 0; i < 6; i++)
1968 for (i1 = 0; i1 < 8; i1++)
1970 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1971 ddsd.dwSize = sizeof(ddsd);
1972 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1973 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1974 if (FAILED(hr)) goto out;
1976 for (y = 0 ; y < ddsd.dwHeight; y++)
1978 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1980 for (x = 0; x < ddsd.dwWidth; x++)
1982 /* face number in low 4 bits of red, x stored in green component, y in blue. */
1983 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
1984 *textureRow++ = color;
1988 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
1989 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1992 for (i = 0; i < 6; i++)
1993 for (i1 = 0; i1 < 8; i1++)
1995 memset(&ddbltfx, 0, sizeof(ddbltfx));
1996 ddbltfx.dwSize = sizeof(ddbltfx);
1997 U5(ddbltfx).dwFillColor = 0;
1998 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1999 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2002 loadpoint.x = loadpoint.y = 10;
2003 loadrect.left = 30;
2004 loadrect.top = 20;
2005 loadrect.right = 93;
2006 loadrect.bottom = 52;
2008 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2009 DDSCAPS2_CUBEMAP_ALLFACES);
2010 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2012 for (i = 0; i < 6; i++)
2014 loadpoint.x = loadpoint.y = 10;
2015 loadrect.left = 30;
2016 loadrect.top = 20;
2017 loadrect.right = 93;
2018 loadrect.bottom = 52;
2020 for (i1 = 0; i1 < 8; i1++)
2022 diff_count = 0;
2023 diff_count2 = 0;
2025 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2026 ddsd.dwSize = sizeof(ddsd);
2027 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2028 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2029 if (FAILED(hr)) goto out;
2031 for (y = 0 ; y < ddsd.dwHeight; y++)
2033 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2035 for (x = 0; x < ddsd.dwWidth; x++)
2037 DWORD color = *textureRow++;
2039 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2040 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2042 if (color & 0xffffff) diff_count++;
2044 else
2046 DWORD r = (color & 0xff0000) >> 16;
2047 DWORD g = (color & 0xff00) >> 8;
2048 DWORD b = (color & 0xff);
2050 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2051 b != y + loadrect.top - loadpoint.y) diff_count++;
2054 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2055 technically be correct as it's not precisely defined by docs. */
2056 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2057 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2059 if (color & 0xffffff) diff_count2++;
2061 else
2063 DWORD r = (color & 0xff0000) >> 16;
2064 DWORD g = (color & 0xff00) >> 8;
2065 DWORD b = (color & 0xff);
2067 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2068 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2073 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2074 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2076 ok(diff_count == 0 || diff_count2 == 0,
2077 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2078 MIN(diff_count, diff_count2), i, i1);
2080 loadpoint.x /= 2;
2081 loadpoint.y /= 2;
2082 loadrect.top /= 2;
2083 loadrect.left /= 2;
2084 loadrect.right = (loadrect.right + 1) / 2;
2085 loadrect.bottom = (loadrect.bottom + 1) / 2;
2089 for (i = 0; i < 2; i++)
2090 for (i1 = 5; i1 >= 0; i1--)
2091 for (i2 = 7; i2 >= 0; i2--)
2093 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2095 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2097 /* Test cubemap loading from regular texture. */
2098 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2099 ddsd.dwSize = sizeof(ddsd);
2100 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2101 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2102 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2103 ddsd.dwWidth = 128;
2104 ddsd.dwHeight = 128;
2105 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2106 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2107 if (FAILED(hr)) goto out;
2109 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2110 ddsd.dwSize = sizeof(ddsd);
2111 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2112 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2113 ddsd.dwWidth = 128;
2114 ddsd.dwHeight = 128;
2115 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2116 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2117 if (FAILED(hr)) goto out;
2119 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2120 DDSCAPS2_CUBEMAP_ALLFACES);
2121 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2123 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2124 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2125 IDirectDrawSurface7_Release(texture_levels[0][0]);
2126 memset(texture_levels, 0, sizeof(texture_levels));
2128 /* Test cubemap loading from cubemap with different number of faces. */
2129 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2130 ddsd.dwSize = sizeof(ddsd);
2131 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2132 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2133 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
2134 ddsd.dwWidth = 128;
2135 ddsd.dwHeight = 128;
2136 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2137 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2138 if (FAILED(hr)) goto out;
2140 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2141 ddsd.dwSize = sizeof(ddsd);
2142 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2143 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2144 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY;
2145 ddsd.dwWidth = 128;
2146 ddsd.dwHeight = 128;
2147 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[1][0][0], NULL);
2148 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2149 if (FAILED(hr)) goto out;
2151 /* INVALIDPARAMS tests currently would fail because wine doesn't support partial cube faces
2152 (the above created cubemaps will have all faces. */
2153 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2154 DDSCAPS2_CUBEMAP_ALLFACES);
2155 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2157 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2158 DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY);
2159 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2161 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2162 DDSCAPS2_CUBEMAP_POSITIVEX);
2163 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2165 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2166 DDSCAPS2_CUBEMAP_ALLFACES);
2167 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2169 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2170 DDSCAPS2_CUBEMAP_POSITIVEX);
2171 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2173 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2174 DDSCAPS2_CUBEMAP_POSITIVEZ);
2175 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2177 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2178 IDirectDrawSurface7_Release(cube_face_levels[1][0][0]);
2179 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2182 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2183 for (i = 0; i < 2; i++)
2185 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2186 ddsd.dwSize = sizeof(ddsd);
2187 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2188 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2189 ddsd.dwWidth = 128;
2190 ddsd.dwHeight = 128;
2191 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2192 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2193 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2194 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2195 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2196 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2197 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2198 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2199 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2200 if (FAILED(hr)) goto out;
2202 /* Check the number of created mipmaps */
2203 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2204 ddsd.dwSize = sizeof(ddsd);
2205 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2206 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2207 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2208 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2210 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2212 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2213 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2214 if (FAILED(hr)) goto out;
2218 for (i1 = 0; i1 < 8; i1++)
2220 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2221 ddsd.dwSize = sizeof(ddsd);
2222 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2223 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2224 if (FAILED(hr)) goto out;
2226 for (y = 0 ; y < ddsd.dwHeight; y++)
2228 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2230 for (x = 0; x < ddsd.dwWidth; x++)
2232 /* x stored in green component, y in blue. */
2233 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2234 *textureRow++ = color;
2238 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2239 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2242 for (i1 = 0; i1 < 4; i1++)
2244 memset(&ddbltfx, 0, sizeof(ddbltfx));
2245 ddbltfx.dwSize = sizeof(ddbltfx);
2246 U5(ddbltfx).dwFillColor = 0;
2247 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2248 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2251 loadpoint.x = loadpoint.y = 31;
2252 loadrect.left = 30;
2253 loadrect.top = 20;
2254 loadrect.right = 93;
2255 loadrect.bottom = 52;
2257 /* Destination mip levels are a subset of source mip levels. */
2258 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2259 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2261 for (i1 = 0; i1 < 4; i1++)
2263 diff_count = 0;
2264 diff_count2 = 0;
2266 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2267 ddsd.dwSize = sizeof(ddsd);
2268 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2269 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2270 if (FAILED(hr)) goto out;
2272 for (y = 0 ; y < ddsd.dwHeight; y++)
2274 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2276 for (x = 0; x < ddsd.dwWidth; x++)
2278 DWORD color = *textureRow++;
2280 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2281 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2283 if (color & 0xffffff) diff_count++;
2285 else
2287 DWORD r = (color & 0xff0000) >> 16;
2288 DWORD g = (color & 0xff00) >> 8;
2289 DWORD b = (color & 0xff);
2291 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2292 b != y + loadrect.top - loadpoint.y) diff_count++;
2295 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2296 technically be correct as it's not precisely defined by docs. */
2297 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2298 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2300 if (color & 0xffffff) diff_count2++;
2302 else
2304 DWORD r = (color & 0xff0000) >> 16;
2305 DWORD g = (color & 0xff00) >> 8;
2306 DWORD b = (color & 0xff);
2308 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2309 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2314 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2315 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2317 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2318 MIN(diff_count, diff_count2), i1);
2320 loadpoint.x /= 2;
2321 loadpoint.y /= 2;
2322 loadrect.top /= 2;
2323 loadrect.left /= 2;
2324 loadrect.right = (loadrect.right + 1) / 2;
2325 loadrect.bottom = (loadrect.bottom + 1) / 2;
2328 /* Destination mip levels are a superset of source mip levels (should fail). */
2329 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2330 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2332 for (i = 0; i < 2; i++)
2334 for (i1 = 7; i1 >= 0; i1--)
2336 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2339 memset(texture_levels, 0, sizeof(texture_levels));
2341 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2342 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2343 ddsd.dwSize = sizeof(ddsd);
2344 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2345 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2346 ddsd.dwWidth = 128;
2347 ddsd.dwHeight = 128;
2348 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2349 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2350 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2351 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2352 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2353 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2354 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2355 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2356 if (FAILED(hr)) goto out;
2358 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2359 ddsd.dwSize = sizeof(ddsd);
2360 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2361 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2362 ddsd.dwWidth = 32;
2363 ddsd.dwHeight = 32;
2364 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2365 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2366 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2367 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2368 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2369 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2370 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2371 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2372 if (FAILED(hr)) goto out;
2374 for (i1 = 1; i1 < 8; i1++)
2376 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2377 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2378 if (FAILED(hr)) goto out;
2381 for (i1 = 0; i1 < 8; i1++)
2383 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2384 ddsd.dwSize = sizeof(ddsd);
2385 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2386 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2387 if (FAILED(hr)) goto out;
2389 for (y = 0 ; y < ddsd.dwHeight; y++)
2391 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2393 for (x = 0; x < ddsd.dwWidth; x++)
2395 /* x stored in green component, y in blue. */
2396 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2397 *textureRow++ = color;
2401 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2402 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2405 memset(&ddbltfx, 0, sizeof(ddbltfx));
2406 ddbltfx.dwSize = sizeof(ddbltfx);
2407 U5(ddbltfx).dwFillColor = 0;
2408 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2409 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2411 loadpoint.x = loadpoint.y = 32;
2412 loadrect.left = 32;
2413 loadrect.top = 32;
2414 loadrect.right = 96;
2415 loadrect.bottom = 96;
2417 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2418 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2420 loadpoint.x /= 4;
2421 loadpoint.y /= 4;
2422 loadrect.top /= 4;
2423 loadrect.left /= 4;
2424 loadrect.right = (loadrect.right + 3) / 4;
2425 loadrect.bottom = (loadrect.bottom + 3) / 4;
2427 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2428 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2429 * copied subrectangles divided more than needed, without apparent logic. But it works
2430 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2431 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2432 * The following code attempts to detect broken results, actual tests will then be skipped
2434 load_mip_subset_broken = TRUE;
2435 diff_count = 0;
2437 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2438 ddsd.dwSize = sizeof(ddsd);
2439 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2440 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2441 if (FAILED(hr)) goto out;
2443 for (y = 0 ; y < ddsd.dwHeight; y++)
2445 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2447 for (x = 0; x < ddsd.dwWidth; x++)
2449 DWORD color = *textureRow++;
2451 if (x < 2 || x >= 2 + 4 ||
2452 y < 2 || y >= 2 + 4)
2454 if (color & 0xffffff) diff_count++;
2456 else
2458 DWORD r = (color & 0xff0000) >> 16;
2460 if ((r & (0xf0)) != 0xf0) diff_count++;
2465 if (diff_count) load_mip_subset_broken = FALSE;
2467 if (load_mip_subset_broken) {
2468 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2469 } else {
2470 diff_count = 0;
2472 for (y = 0 ; y < ddsd.dwHeight; y++)
2474 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2476 for (x = 0; x < ddsd.dwWidth; x++)
2478 DWORD color = *textureRow++;
2480 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2481 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2483 if (color & 0xffffff) diff_count++;
2485 else
2487 DWORD r = (color & 0xff0000) >> 16;
2488 DWORD g = (color & 0xff00) >> 8;
2489 DWORD b = (color & 0xff);
2491 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2492 b != y + loadrect.top - loadpoint.y) diff_count++;
2498 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2499 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2501 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2503 for (i = 0; i < 2; i++)
2505 for (i1 = 7; i1 >= 0; i1--)
2507 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2510 memset(texture_levels, 0, sizeof(texture_levels));
2512 if (!load_mip_subset_broken)
2514 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2515 * surface (than first source mip level)
2517 for (i = 0; i < 2; i++)
2519 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2520 ddsd.dwSize = sizeof(ddsd);
2521 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2522 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2523 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2524 ddsd.dwWidth = i ? 32 : 128;
2525 ddsd.dwHeight = i ? 32 : 128;
2526 if (i) U2(ddsd).dwMipMapCount = 4;
2527 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2528 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2529 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2530 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2531 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2532 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2533 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2534 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2535 if (FAILED(hr)) goto out;
2537 /* Check the number of created mipmaps */
2538 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2539 ddsd.dwSize = sizeof(ddsd);
2540 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2541 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2542 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2543 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2545 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2547 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2548 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2549 if (FAILED(hr)) goto out;
2553 for (i1 = 0; i1 < 8; i1++)
2555 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2556 ddsd.dwSize = sizeof(ddsd);
2557 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2558 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2559 if (FAILED(hr)) goto out;
2561 for (y = 0 ; y < ddsd.dwHeight; y++)
2563 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2565 for (x = 0; x < ddsd.dwWidth; x++)
2567 /* x stored in green component, y in blue. */
2568 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2569 *textureRow++ = color;
2573 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2574 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2577 for (i1 = 0; i1 < 4; i1++)
2579 memset(&ddbltfx, 0, sizeof(ddbltfx));
2580 ddbltfx.dwSize = sizeof(ddbltfx);
2581 U5(ddbltfx).dwFillColor = 0;
2582 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2583 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2586 loadpoint.x = loadpoint.y = 0;
2587 loadrect.left = 0;
2588 loadrect.top = 0;
2589 loadrect.right = 64;
2590 loadrect.bottom = 64;
2592 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2593 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2595 i = 0;
2596 for (i1 = 0; i1 < 8 && i < 4; i1++)
2598 DDSURFACEDESC2 ddsd2;
2600 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2601 ddsd.dwSize = sizeof(ddsd);
2602 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2603 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2605 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2606 ddsd2.dwSize = sizeof(ddsd2);
2607 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2608 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2610 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2612 diff_count = 0;
2614 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2615 ddsd.dwSize = sizeof(ddsd);
2616 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], 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 DWORD color = *textureRow++;
2628 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2629 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2631 if (color & 0xffffff) diff_count++;
2633 else
2635 DWORD r = (color & 0xff0000) >> 16;
2636 DWORD g = (color & 0xff00) >> 8;
2637 DWORD b = (color & 0xff);
2639 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2640 b != y + loadrect.top - loadpoint.y) diff_count++;
2645 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2646 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2648 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2650 i++;
2653 loadpoint.x /= 2;
2654 loadpoint.y /= 2;
2655 loadrect.top /= 2;
2656 loadrect.left /= 2;
2657 loadrect.right = (loadrect.right + 1) / 2;
2658 loadrect.bottom = (loadrect.bottom + 1) / 2;
2661 for (i = 0; i < 2; i++)
2663 for (i1 = 7; i1 >= 0; i1--)
2665 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2668 memset(texture_levels, 0, sizeof(texture_levels));
2671 /* Test palette copying. */
2672 for (i = 0; i < 2; i++)
2674 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2675 ddsd.dwSize = sizeof(ddsd);
2676 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2677 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2678 ddsd.dwWidth = 128;
2679 ddsd.dwHeight = 128;
2680 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2681 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2682 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2683 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2684 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2685 if (FAILED(hr)) goto out;
2687 /* Check the number of created mipmaps */
2688 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2689 ddsd.dwSize = sizeof(ddsd);
2690 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2691 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2692 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2693 if (U2(ddsd).dwMipMapCount != 8) goto out;
2695 for (i1 = 1; i1 < 8; i1++)
2697 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2698 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2699 if (FAILED(hr)) goto out;
2703 memset(table1, 0, sizeof(table1));
2704 for (i = 0; i < 3; i++)
2706 table1[0].peBlue = i + 1;
2707 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2708 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2709 if (FAILED(hr))
2711 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2712 goto out;
2716 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2717 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2719 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2720 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2722 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2723 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2725 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2726 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2727 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2728 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2730 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2731 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2733 memset(table1, 0, sizeof(table1));
2734 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2735 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2736 if (SUCCEEDED(hr))
2738 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2739 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2740 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2743 /* Test colorkey copying. */
2744 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2745 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2746 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2747 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2748 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2750 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2751 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2753 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2754 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2756 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2757 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2758 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2759 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2761 out:
2763 for (i = 0; i < 5; i++)
2765 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2768 for (i = 0; i < 2; i++)
2770 for (i1 = 7; i1 >= 0; i1--)
2772 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2776 for (i = 0; i < 2; i++)
2777 for (i1 = 5; i1 >= 0; i1--)
2778 for (i2 = 7; i2 >= 0; i2--)
2780 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2784 static void SetMaterialTest(void)
2786 HRESULT rc;
2788 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2789 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2792 static void ComputeSphereVisibility(void)
2794 D3DMATRIX proj, view, world;
2795 D3DVALUE radius[3];
2796 D3DVECTOR center[3];
2797 DWORD result[3];
2798 HRESULT rc;
2800 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
2801 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
2802 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
2803 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
2805 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
2806 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
2807 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
2808 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
2810 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
2811 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
2812 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
2813 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
2815 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
2816 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2817 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2819 U1(center[0]).x=11.461533;
2820 U2(center[0]).y=-4.761727;
2821 U3(center[0]).z=-1.171646;
2823 radius[0]=38.252632;
2825 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2827 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2828 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
2830 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
2831 radius[0]=4.354097;
2832 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
2833 radius[1]=12.500704;
2834 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
2835 radius[2]=17.251318;
2837 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
2839 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2840 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2841 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2842 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
2843 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2844 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
2846 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
2847 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
2848 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
2849 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
2851 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2852 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
2853 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
2854 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2856 U1(center[0]).x=0.0;
2857 U2(center[0]).y=0.0;
2858 U3(center[0]).z=0.05;
2860 radius[0]=0.04;
2862 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2863 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2865 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2867 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2868 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2870 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
2871 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
2872 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
2873 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
2875 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2877 U1(center[0]).x=0.0;
2878 U2(center[0]).y=0.0;
2879 U3(center[0]).z=0.5;
2881 radius[0]=0.5;
2883 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2885 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2886 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2888 U1(center[0]).x=0.0;
2889 U2(center[0]).y=0.0;
2890 U3(center[0]).z=0.0;
2892 radius[0]=0.0;
2894 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2896 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2897 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
2899 U1(center[0]).x=-1.0;
2900 U2(center[0]).y=-1.0;
2901 U3(center[0]).z=0.50;
2903 radius[0]=0.25;
2905 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2907 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2908 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
2910 U1(center[0]).x=-20.0;
2911 U2(center[0]).y=0.0;
2912 U3(center[0]).z=0.50;
2914 radius[0]=3.0;
2916 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2918 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2919 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2921 U1(center[0]).x=20.0;
2922 U2(center[0]).y=0.0;
2923 U3(center[0]).z=0.50;
2925 radius[0]=3.0f;
2927 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2929 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2930 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
2932 U1(center[0]).x=0.0;
2933 U2(center[0]).y=-20.0;
2934 U3(center[0]).z=0.50;
2936 radius[0]=3.0;
2938 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2940 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2941 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
2943 U1(center[0]).x=0.0;
2944 U2(center[0]).y=20.0;
2945 U3(center[0]).z=0.5;
2947 radius[0]=3.0;
2949 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2951 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2952 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
2954 U1(center[0]).x=0.0;
2955 U2(center[0]).y=0.0;
2956 U3(center[0]).z=-20;
2958 radius[0]=3.0;
2960 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2962 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2963 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
2965 U1(center[0]).x=0.0;
2966 U2(center[0]).y=0.0;
2967 U3(center[0]).z=20.0;
2969 radius[0]=3.0;
2971 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2973 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2974 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
2977 static void SetRenderTargetTest(void)
2979 HRESULT hr;
2980 IDirectDrawSurface7 *newrt, *oldrt;
2981 D3DVIEWPORT7 vp;
2982 DDSURFACEDESC2 ddsd;
2983 DWORD stateblock;
2985 memset(&ddsd, 0, sizeof(ddsd));
2986 ddsd.dwSize = sizeof(ddsd);
2987 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2988 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
2989 ddsd.dwWidth = 64;
2990 ddsd.dwHeight = 64;
2991 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
2992 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
2993 if(FAILED(hr))
2995 skip("Skipping SetRenderTarget test\n");
2996 return;
2999 memset(&vp, 0, sizeof(vp));
3000 vp.dwX = 10;
3001 vp.dwY = 10;
3002 vp.dwWidth = 246;
3003 vp.dwHeight = 246;
3004 vp.dvMinZ = 0.25;
3005 vp.dvMaxZ = 0.75;
3006 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3007 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3009 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3010 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3012 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3013 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3014 memset(&vp, 0xff, sizeof(vp));
3015 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3016 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3017 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3018 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3019 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3020 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3021 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.1\n", vp.dvMinZ);
3022 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.9\n", vp.dvMaxZ);
3024 memset(&vp, 0, sizeof(vp));
3025 vp.dwX = 0;
3026 vp.dwY = 0;
3027 vp.dwWidth = 64;
3028 vp.dwHeight = 64;
3029 vp.dvMinZ = 0.0;
3030 vp.dvMaxZ = 1.0;
3031 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3032 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3034 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3035 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3036 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3037 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3039 /* Check this twice, before and after ending the stateblock */
3040 memset(&vp, 0xff, sizeof(vp));
3041 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3042 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3043 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3044 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3045 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3046 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3047 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3048 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3050 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3051 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3053 memset(&vp, 0xff, sizeof(vp));
3054 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3055 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3056 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3057 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3058 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3059 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3060 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3061 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3063 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3064 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3066 memset(&vp, 0, sizeof(vp));
3067 vp.dwX = 0;
3068 vp.dwY = 0;
3069 vp.dwWidth = 256;
3070 vp.dwHeight = 256;
3071 vp.dvMinZ = 0.0;
3072 vp.dvMaxZ = 0.0;
3073 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3074 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3076 IDirectDrawSurface7_Release(oldrt);
3077 IDirectDrawSurface7_Release(newrt);
3080 static UINT expect_message;
3082 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3084 if (expect_message && message == expect_message) expect_message = 0;
3086 return DefWindowProcA(hwnd, message, wparam, lparam);
3089 static void test_wndproc(void)
3091 IDirectDraw7 *ddraw7;
3092 WNDCLASSA wc = {0};
3093 LONG_PTR proc;
3094 HWND window;
3095 HRESULT hr;
3096 ULONG ref;
3098 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3099 if (FAILED(hr))
3101 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3102 return;
3105 wc.lpfnWndProc = test_proc;
3106 wc.lpszClassName = "d3d7_test_wndproc_wc";
3107 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3109 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3110 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3112 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3113 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3114 (LONG_PTR)test_proc, proc);
3116 expect_message = WM_SETFOCUS;
3118 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3119 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3120 if (FAILED(hr))
3122 IDirectDraw7_Release(ddraw7);
3123 goto done;
3126 todo_wine ok(!expect_message, "Expected message %#x, but didn't receive it.\n", expect_message);
3128 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3129 todo_wine ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3130 (LONG_PTR)test_proc, proc);
3132 ref = IDirectDraw7_Release(ddraw7);
3133 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3135 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3136 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3137 (LONG_PTR)test_proc, proc);
3139 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3140 if (FAILED(hr))
3142 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3143 return;
3146 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3147 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3148 (LONG_PTR)test_proc, proc);
3150 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3151 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3152 if (FAILED(hr))
3154 IDirectDraw7_Release(ddraw7);
3155 goto done;
3158 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3159 todo_wine ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3160 (LONG_PTR)test_proc, proc);
3162 ref = IDirectDraw7_Release(ddraw7);
3163 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3165 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3166 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3167 (LONG_PTR)DefWindowProcA, proc);
3169 done:
3170 expect_message = 0;
3171 DestroyWindow(window);
3172 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3175 static void VertexBufferLockRest(void)
3177 D3DVERTEXBUFFERDESC desc;
3178 IDirect3DVertexBuffer7 *buffer;
3179 HRESULT hr;
3180 unsigned int i;
3181 void *data;
3182 const struct
3184 DWORD flags;
3185 const char *debug_string;
3186 HRESULT result;
3188 test_data[] =
3190 {0, "(none)", D3D_OK },
3191 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3192 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3193 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3194 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3195 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3196 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3197 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3199 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3200 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3201 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3204 memset(&desc, 0 , sizeof(desc));
3205 desc.dwSize = sizeof(desc);
3206 desc.dwCaps = 0;
3207 desc.dwFVF = D3DFVF_XYZ;
3208 desc.dwNumVertices = 64;
3209 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3210 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3212 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3214 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3215 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3216 test_data[i].debug_string, hr, test_data[i].result);
3217 if(SUCCEEDED(hr))
3219 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3220 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3221 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3225 IDirect3DVertexBuffer7_Release(buffer);
3228 START_TEST(d3d)
3230 init_function_pointers();
3231 if(!pDirectDrawCreateEx) {
3232 win_skip("function DirectDrawCreateEx not available\n");
3233 return;
3236 if(!CreateDirect3D()) {
3237 skip("Skipping d3d7 tests\n");
3238 } else {
3239 LightTest();
3240 ProcessVerticesTest();
3241 StateTest();
3242 SceneTest();
3243 LimitTest();
3244 D3D7EnumTest();
3245 SetMaterialTest();
3246 ComputeSphereVisibility();
3247 CapsTest();
3248 VertexBufferDescTest();
3249 D3D7_OldRenderStateTest();
3250 DeviceLoadTest();
3251 SetRenderTargetTest();
3252 VertexBufferLockRest();
3253 ReleaseDirect3D();
3256 if (!D3D1_createObjects()) {
3257 skip("Skipping d3d1 tests\n");
3258 } else {
3259 Direct3D1Test();
3260 TextureLoadTest();
3261 D3D1_releaseObjects();
3264 test_wndproc();