ddraw/tests: Add an observation regarding device color model criteria for IDirect3D3...
[wine/testsucceed.git] / dlls / ddraw / tests / d3d.c
blob069bc963fde71f5b7c171daf3a2d1b96ea07465e
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 static void ViewportTest(void)
1033 HRESULT hr;
1034 LPDIRECT3DVIEWPORT2 Viewport2;
1035 D3DVIEWPORT vp1_data, ret_vp1_data;
1036 D3DVIEWPORT2 vp2_data, ret_vp2_data;
1037 float infinity;
1039 *(DWORD*)&infinity = 0x7f800000;
1041 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1042 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1044 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
1045 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1047 vp1_data.dwSize = sizeof(vp1_data);
1048 vp1_data.dwX = 0;
1049 vp1_data.dwY = 1;
1050 vp1_data.dwWidth = 256;
1051 vp1_data.dwHeight = 257;
1052 vp1_data.dvMaxX = 0;
1053 vp1_data.dvMaxY = 0;
1054 vp1_data.dvScaleX = 0;
1055 vp1_data.dvScaleY = 0;
1056 vp1_data.dvMinZ = 0.25;
1057 vp1_data.dvMaxZ = 0.75;
1059 vp2_data.dwSize = sizeof(vp2_data);
1060 vp2_data.dwX = 2;
1061 vp2_data.dwY = 3;
1062 vp2_data.dwWidth = 258;
1063 vp2_data.dwHeight = 259;
1064 vp2_data.dvClipX = 0;
1065 vp2_data.dvClipY = 0;
1066 vp2_data.dvClipWidth = 0;
1067 vp2_data.dvClipHeight = 0;
1068 vp2_data.dvMinZ = 0.1;
1069 vp2_data.dvMaxZ = 0.9;
1071 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1072 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1074 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1075 ret_vp1_data.dwSize = sizeof(vp1_data);
1077 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1078 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1080 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1081 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1082 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1083 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1084 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1085 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1086 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1087 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1088 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1089 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1091 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1092 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1094 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1095 ret_vp2_data.dwSize = sizeof(vp2_data);
1097 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1098 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1100 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1101 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1102 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1103 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1104 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1105 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1106 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1107 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1108 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1109 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1110 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1111 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1113 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1114 ret_vp1_data.dwSize = sizeof(vp1_data);
1116 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1117 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1119 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1120 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1121 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1122 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1123 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1124 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1125 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1126 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1127 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1128 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1130 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1131 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1133 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1134 ret_vp2_data.dwSize = sizeof(vp2_data);
1136 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1137 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1139 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1140 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1141 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1142 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1143 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1144 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1145 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1146 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1147 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1148 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1149 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1150 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1152 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1153 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1155 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1156 ret_vp1_data.dwSize = sizeof(vp1_data);
1158 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1159 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1161 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1162 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1163 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1164 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1165 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1166 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1167 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1168 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1169 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1170 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1172 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1173 ret_vp2_data.dwSize = sizeof(vp2_data);
1175 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1176 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1178 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1179 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1180 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1181 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1182 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1183 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1184 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1185 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1186 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1187 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1188 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1189 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1191 IDirect3DViewport2_Release(Viewport2);
1193 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1194 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1197 #define SET_VP_DATA(vp_data) \
1198 vp_data.dwSize = sizeof(vp_data); \
1199 vp_data.dwX = 0; \
1200 vp_data.dwY = 0; \
1201 vp_data.dwWidth = 256; \
1202 vp_data.dwHeight = 256; \
1203 vp_data.dvMaxX = 256; \
1204 vp_data.dvMaxY = 256; \
1205 vp_data.dvScaleX = 5; \
1206 vp_data.dvScaleY = 5; \
1207 vp_data.dvMinZ = -25; \
1208 vp_data.dvMaxZ = 60;
1210 static void Direct3D1Test(void)
1212 HRESULT hr;
1213 D3DEXECUTEBUFFERDESC desc;
1214 D3DVIEWPORT vp_data;
1215 D3DINSTRUCTION *instr;
1216 D3DBRANCH *branch;
1217 IDirect3D *Direct3D_alt;
1218 IDirect3DLight *d3dlight;
1219 ULONG refcount;
1220 unsigned int idx = 0;
1221 static struct v_in testverts[] = {
1222 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1223 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1225 static struct v_in cliptest[] = {
1226 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1227 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1229 static struct v_in offscreentest[] = {
1230 {128.1, 0.0, 0.0},
1232 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1233 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1234 D3DTRANSFORMDATA transformdata;
1235 DWORD i = FALSE;
1237 /* Interface consistency check. */
1238 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1239 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1240 if (hr == D3D_OK)
1241 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1243 memset(&desc, 0, sizeof(desc));
1244 desc.dwSize = sizeof(desc);
1245 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1246 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1248 memset(desc.lpData, 0, 128);
1249 instr = desc.lpData;
1250 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1251 instr[idx].bSize = sizeof(*branch);
1252 instr[idx].wCount = 1;
1253 idx++;
1254 branch = (D3DBRANCH *) &instr[idx];
1255 branch->dwMask = 0x0;
1256 branch->dwValue = 1;
1257 branch->bNegate = TRUE;
1258 branch->dwOffset = 0;
1259 idx += (sizeof(*branch) / sizeof(*instr));
1260 instr[idx].bOpcode = D3DOP_EXIT;
1261 instr[idx].bSize = 0;
1262 instr[idx].wCount = 0;
1263 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1264 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1266 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1267 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1269 memset(&desc, 0, sizeof(desc));
1270 desc.dwSize = sizeof(desc);
1272 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1273 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1275 memset(desc.lpData, 0, 128);
1276 instr = desc.lpData;
1277 idx = 0;
1278 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1279 instr[idx].bSize = sizeof(*branch);
1280 instr[idx].wCount = 1;
1281 idx++;
1282 branch = (D3DBRANCH *) &instr[idx];
1283 branch->dwMask = 0x0;
1284 branch->dwValue = 1;
1285 branch->bNegate = TRUE;
1286 branch->dwOffset = 64;
1287 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1288 instr[0].bOpcode = D3DOP_EXIT;
1289 instr[0].bSize = 0;
1290 instr[0].wCount = 0;
1291 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1292 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1294 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1295 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1297 /* Test rendering 0 triangles */
1298 memset(&desc, 0, sizeof(desc));
1299 desc.dwSize = sizeof(desc);
1301 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1302 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1304 memset(desc.lpData, 0, 128);
1305 instr = desc.lpData;
1306 idx = 0;
1308 instr->bOpcode = D3DOP_TRIANGLE;
1309 instr->bSize = sizeof(D3DOP_TRIANGLE);
1310 instr->wCount = 0;
1311 instr++;
1312 instr->bOpcode = D3DOP_EXIT;
1313 instr->bSize = 0;
1314 instr->wCount = 0;
1315 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1316 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1318 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1319 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1321 memset(&transformdata, 0, sizeof(transformdata));
1322 transformdata.dwSize = sizeof(transformdata);
1323 transformdata.lpIn = testverts;
1324 transformdata.dwInSize = sizeof(testverts[0]);
1325 transformdata.lpOut = out;
1326 transformdata.dwOutSize = sizeof(out[0]);
1328 transformdata.lpHOut = NULL;
1329 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1330 &transformdata, D3DTRANSFORM_UNCLIPPED,
1331 &i);
1332 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1334 transformdata.lpHOut = outH;
1335 memset(outH, 0xcc, sizeof(outH));
1336 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1337 &transformdata, D3DTRANSFORM_UNCLIPPED,
1338 &i);
1339 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1340 ok(i == 0, "Offscreen is %d\n", i);
1342 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1343 static const struct v_out cmp[] = {
1344 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1345 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1348 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1349 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1350 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1351 out[i].x, out[i].y, out[i].z, out[i].rhw,
1352 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1354 for(i = 0; i < sizeof(outH); i++) {
1355 if(((unsigned char *) outH)[i] != 0xcc) {
1356 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1357 break;
1361 SET_VP_DATA(vp_data);
1362 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1363 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1364 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1365 &transformdata, D3DTRANSFORM_UNCLIPPED,
1366 &i);
1367 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1368 ok(i == 0, "Offscreen is %d\n", i);
1370 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1371 static const struct v_out cmp[] = {
1372 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1373 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1375 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1376 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1377 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1378 out[i].x, out[i].y, out[i].z, out[i].rhw,
1379 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1382 SET_VP_DATA(vp_data);
1383 vp_data.dwX = 10;
1384 vp_data.dwY = 20;
1385 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1386 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1387 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1388 &transformdata, D3DTRANSFORM_UNCLIPPED,
1389 &i);
1390 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1391 ok(i == 0, "Offscreen is %d\n", i);
1392 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1393 static const struct v_out cmp[] = {
1394 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1395 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1397 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1398 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1399 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1400 out[i].x, out[i].y, out[i].z, out[i].rhw,
1401 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1404 memset(out, 0xcc, sizeof(out));
1405 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1406 &transformdata, D3DTRANSFORM_CLIPPED,
1407 &i);
1408 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1409 ok(i == 0, "Offscreen is %d\n", i);
1410 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1411 static const D3DHVERTEX cmpH[] = {
1412 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1413 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1414 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1416 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1417 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1418 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1419 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1420 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1422 /* No scheme has been found behind those return values. It seems to be
1423 * whatever data windows has when throwing the vertex away. Modify the
1424 * input test vertices to test this more. Depending on the input data
1425 * it can happen that the z coord gets written into y, or similar things
1427 if(0)
1429 static const struct v_out cmp[] = {
1430 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1431 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1433 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1434 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1435 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1436 out[i].x, out[i].y, out[i].z, out[i].rhw,
1437 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1440 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1441 ok(((DWORD *) out)[i] != 0xcccccccc,
1442 "Regular output DWORD %d remained untouched\n", i);
1445 transformdata.lpIn = cliptest;
1446 transformdata.dwInSize = sizeof(cliptest[0]);
1447 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1448 &transformdata, D3DTRANSFORM_CLIPPED,
1449 &i);
1450 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1451 ok(i == 0, "Offscreen is %d\n", i);
1452 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1453 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1457 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1458 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1460 ok(Flags[i] == outH[i].dwFlags,
1461 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1462 outH[i].dwFlags, Flags[i]);
1465 SET_VP_DATA(vp_data);
1466 vp_data.dwWidth = 10;
1467 vp_data.dwHeight = 1000;
1468 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1469 i = 10;
1470 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1471 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1472 &transformdata, D3DTRANSFORM_CLIPPED,
1473 &i);
1474 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1475 ok(i == 0, "Offscreen is %d\n", i);
1476 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1477 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1479 D3DCLIP_RIGHT,
1480 D3DCLIP_LEFT,
1481 D3DCLIP_RIGHT | D3DCLIP_BACK,
1482 D3DCLIP_LEFT | D3DCLIP_FRONT,
1484 ok(Flags[i] == outH[i].dwFlags,
1485 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1486 outH[i].dwFlags, Flags[i]);
1489 SET_VP_DATA(vp_data);
1490 vp_data.dwWidth = 256;
1491 vp_data.dwHeight = 256;
1492 vp_data.dvScaleX = 1;
1493 vp_data.dvScaleY = 1;
1494 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1495 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1496 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1497 &transformdata, D3DTRANSFORM_CLIPPED,
1498 &i);
1499 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1500 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1501 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1502 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1506 D3DCLIP_BACK,
1507 D3DCLIP_FRONT,
1509 ok(Flags[i] == outH[i].dwFlags,
1510 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1511 outH[i].dwFlags, Flags[i]);
1514 /* Finally try to figure out how the DWORD dwOffscreen works.
1515 * Apparently no vertex is offscreen with clipping off,
1516 * and with clipping on the offscreen flag is set if only one vertex
1517 * is transformed, and this vertex is offscreen.
1519 SET_VP_DATA(vp_data);
1520 vp_data.dwWidth = 5;
1521 vp_data.dwHeight = 5;
1522 vp_data.dvScaleX = 10000;
1523 vp_data.dvScaleY = 10000;
1524 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1525 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1526 transformdata.lpIn = cliptest;
1527 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1528 &transformdata, D3DTRANSFORM_UNCLIPPED,
1529 &i);
1530 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1531 ok(i == 0, "Offscreen is %d\n", i);
1532 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1533 &transformdata, D3DTRANSFORM_CLIPPED,
1534 &i);
1535 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1536 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1537 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1538 &transformdata, D3DTRANSFORM_CLIPPED,
1539 &i);
1540 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1541 ok(i == 0, "Offscreen is %d\n", i);
1542 transformdata.lpIn = cliptest + 1;
1543 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1544 &transformdata, D3DTRANSFORM_CLIPPED,
1545 &i);
1546 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1547 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1549 transformdata.lpIn = offscreentest;
1550 transformdata.dwInSize = sizeof(offscreentest[0]);
1551 SET_VP_DATA(vp_data);
1552 vp_data.dwWidth = 257;
1553 vp_data.dwHeight = 257;
1554 vp_data.dvScaleX = 1;
1555 vp_data.dvScaleY = 1;
1556 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1557 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1558 i = 12345;
1559 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1560 &transformdata, D3DTRANSFORM_CLIPPED,
1561 &i);
1562 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1563 ok(i == 0, "Offscreen is %d\n", i);
1564 vp_data.dwWidth = 256;
1565 vp_data.dwHeight = 256;
1566 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1567 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1568 i = 12345;
1569 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1570 &transformdata, D3DTRANSFORM_CLIPPED,
1571 &i);
1572 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1573 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1575 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1576 &transformdata, 0,
1577 &i);
1578 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1580 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1581 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1583 hr = IDirect3DViewport_AddLight(Viewport, Light);
1584 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1585 refcount = getRefcount((IUnknown*) Light);
1586 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1588 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1589 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1590 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1591 refcount = getRefcount((IUnknown*) Light);
1592 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1594 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1595 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1596 refcount = getRefcount((IUnknown*) Light);
1597 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1599 IDirect3DLight_Release(Light);
1602 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1604 int i;
1606 for (i = 0; i < 256; i++) {
1607 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1608 table1[i].peBlue != table2[i].peBlue) return FALSE;
1611 return TRUE;
1614 /* test palette handling in IDirect3DTexture_Load */
1615 static void TextureLoadTest(void)
1617 IDirectDrawSurface *TexSurface = NULL;
1618 IDirect3DTexture *Texture = NULL;
1619 IDirectDrawSurface *TexSurface2 = NULL;
1620 IDirect3DTexture *Texture2 = NULL;
1621 IDirectDrawPalette *palette = NULL;
1622 IDirectDrawPalette *palette2 = NULL;
1623 IDirectDrawPalette *palette_tmp = NULL;
1624 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1625 HRESULT hr;
1626 DDSURFACEDESC ddsd;
1627 int i;
1629 memset (&ddsd, 0, sizeof (ddsd));
1630 ddsd.dwSize = sizeof (ddsd);
1631 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1632 ddsd.dwHeight = 128;
1633 ddsd.dwWidth = 128;
1634 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1635 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1636 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1637 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1639 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1640 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1641 if (FAILED(hr)) {
1642 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1643 goto cleanup;
1646 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1647 (void *)&Texture);
1648 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1649 if (FAILED(hr)) {
1650 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1651 goto cleanup;
1654 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1655 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1656 if (FAILED(hr)) {
1657 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1658 goto cleanup;
1661 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1662 (void *)&Texture2);
1663 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1664 if (FAILED(hr)) {
1665 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1666 goto cleanup;
1669 /* test load of Texture to Texture */
1670 hr = IDirect3DTexture_Load(Texture, Texture);
1671 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1673 /* test Load when both textures have no palette */
1674 hr = IDirect3DTexture_Load(Texture2, Texture);
1675 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1677 for (i = 0; i < 256; i++) {
1678 table1[i].peRed = i;
1679 table1[i].peGreen = i;
1680 table1[i].peBlue = i;
1681 table1[i].peFlags = 0;
1684 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1685 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1686 if (FAILED(hr)) {
1687 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1688 goto cleanup;
1691 /* test Load when source texture has palette and destination has no palette */
1692 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1693 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1694 hr = IDirect3DTexture_Load(Texture2, Texture);
1695 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1697 for (i = 0; i < 256; i++) {
1698 table2[i].peRed = 255 - i;
1699 table2[i].peGreen = 255 - i;
1700 table2[i].peBlue = 255 - i;
1701 table2[i].peFlags = 0;
1704 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1705 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1706 if (FAILED(hr)) {
1707 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1708 goto cleanup;
1711 /* test Load when source has no palette and destination has a palette */
1712 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1713 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1714 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1715 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1716 hr = IDirect3DTexture_Load(Texture2, Texture);
1717 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1718 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1719 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1720 if (!palette_tmp) {
1721 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1722 goto cleanup;
1723 } else {
1724 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1725 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1726 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1727 IDirectDrawPalette_Release(palette_tmp);
1730 /* test Load when both textures have palettes */
1731 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1732 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1733 hr = IDirect3DTexture_Load(Texture2, Texture);
1734 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1735 hr = IDirect3DTexture_Load(Texture2, Texture);
1736 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1737 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1738 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1739 if (!palette_tmp) {
1740 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1741 goto cleanup;
1742 } else {
1743 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1744 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1745 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1746 IDirectDrawPalette_Release(palette_tmp);
1749 cleanup:
1751 if (palette) IDirectDrawPalette_Release(palette);
1752 if (palette2) IDirectDrawPalette_Release(palette2);
1753 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1754 if (Texture) IDirect3DTexture_Release(Texture);
1755 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1756 if (Texture2) IDirect3DTexture_Release(Texture2);
1759 static void VertexBufferDescTest(void)
1761 HRESULT rc;
1762 D3DVERTEXBUFFERDESC desc;
1763 union mem_t
1765 D3DVERTEXBUFFERDESC desc2;
1766 unsigned char buffer[512];
1767 } mem;
1769 memset(&desc, 0, sizeof(desc));
1770 desc.dwSize = sizeof(desc);
1771 desc.dwCaps = 0;
1772 desc.dwFVF = D3DFVF_XYZ;
1773 desc.dwNumVertices = 1;
1774 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1775 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1776 if (!lpVBufSrc)
1778 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1779 goto out;
1782 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1783 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1784 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1785 if(rc != D3D_OK)
1786 skip("GetVertexBuffer Failed!\n");
1787 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1788 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1789 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1790 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1791 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1793 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1794 mem.desc2.dwSize = 0;
1795 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1796 if(rc != D3D_OK)
1797 skip("GetVertexBuffer Failed!\n");
1798 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1799 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1800 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1801 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1802 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1804 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1805 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1806 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1807 if(rc != D3D_OK)
1808 skip("GetVertexBuffer Failed!\n");
1809 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1810 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1811 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1812 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1813 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1815 out:
1816 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1819 static void D3D7_OldRenderStateTest(void)
1821 HRESULT rc;
1822 DWORD val;
1824 /* Test reaction to some deprecated states in D3D7.
1826 * IDirect3DDevice7 in Wine currently relays such states to wined3d where they are do-nothing and return 0, instead
1827 * of INVALIDPARAMS. Unless an app is found which cares this is probably ok. What this test shows is that these states
1828 * need not to be handled in D3D7.
1830 todo_wine {
1831 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1832 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %08x\n", rc);
1834 rc = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1835 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %08x\n", rc);
1837 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1838 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %08x\n", rc);
1840 rc = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1841 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %08x\n", rc);
1845 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1846 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1848 static void DeviceLoadTest(void)
1850 DDSURFACEDESC2 ddsd;
1851 IDirectDrawSurface7 *texture_levels[2][8];
1852 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1853 DWORD flags;
1854 HRESULT hr;
1855 DDBLTFX ddbltfx;
1856 RECT loadrect;
1857 POINT loadpoint;
1858 int i, i1, i2;
1859 unsigned diff_count = 0, diff_count2 = 0;
1860 unsigned x, y;
1861 BOOL load_mip_subset_broken = FALSE;
1862 IDirectDrawPalette *palettes[5];
1863 PALETTEENTRY table1[256];
1864 DDCOLORKEY ddckey;
1865 D3DDEVICEDESC7 d3dcaps;
1867 /* Test loading of texture subrectangle with a mipmap surface. */
1868 memset(texture_levels, 0, sizeof(texture_levels));
1869 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1870 memset(palettes, 0, sizeof(palettes));
1872 for (i = 0; i < 2; i++)
1874 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1875 ddsd.dwSize = sizeof(ddsd);
1876 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1877 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1878 ddsd.dwWidth = 128;
1879 ddsd.dwHeight = 128;
1880 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1881 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1882 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1883 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1884 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1885 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1886 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1887 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1888 if (FAILED(hr)) goto out;
1890 /* Check the number of created mipmaps */
1891 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1892 ddsd.dwSize = sizeof(ddsd);
1893 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1894 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1895 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1896 if (U2(ddsd).dwMipMapCount != 8) goto out;
1898 for (i1 = 1; i1 < 8; i1++)
1900 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1901 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1902 if (FAILED(hr)) goto out;
1906 for (i1 = 0; i1 < 8; i1++)
1908 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1909 ddsd.dwSize = sizeof(ddsd);
1910 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1911 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1912 if (FAILED(hr)) goto out;
1914 for (y = 0 ; y < ddsd.dwHeight; y++)
1916 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1918 for (x = 0; x < ddsd.dwWidth; x++)
1920 /* x stored in green component, y in blue. */
1921 DWORD color = 0xff0000 | (x << 8) | y;
1922 *textureRow++ = color;
1926 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1927 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1930 for (i1 = 0; i1 < 8; i1++)
1932 memset(&ddbltfx, 0, sizeof(ddbltfx));
1933 ddbltfx.dwSize = sizeof(ddbltfx);
1934 U5(ddbltfx).dwFillColor = 0;
1935 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1936 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1939 /* First test some broken coordinates. */
1940 loadpoint.x = loadpoint.y = 0;
1941 loadrect.left = 0;
1942 loadrect.top = 0;
1943 loadrect.right = 0;
1944 loadrect.bottom = 0;
1945 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1946 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1948 loadpoint.x = loadpoint.y = 50;
1949 loadrect.left = 0;
1950 loadrect.top = 0;
1951 loadrect.right = 100;
1952 loadrect.bottom = 100;
1953 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1954 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1956 /* Test actual loading. */
1957 loadpoint.x = loadpoint.y = 31;
1958 loadrect.left = 30;
1959 loadrect.top = 20;
1960 loadrect.right = 93;
1961 loadrect.bottom = 52;
1963 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1964 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1966 for (i1 = 0; i1 < 8; i1++)
1968 diff_count = 0;
1969 diff_count2 = 0;
1971 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1972 ddsd.dwSize = sizeof(ddsd);
1973 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1974 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1975 if (FAILED(hr)) goto out;
1977 for (y = 0 ; y < ddsd.dwHeight; y++)
1979 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1981 for (x = 0; x < ddsd.dwWidth; x++)
1983 DWORD color = *textureRow++;
1985 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1986 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1988 if (color & 0xffffff) diff_count++;
1990 else
1992 DWORD r = (color & 0xff0000) >> 16;
1993 DWORD g = (color & 0xff00) >> 8;
1994 DWORD b = (color & 0xff);
1996 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1999 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2000 technically be correct as it's not precisely defined by docs. */
2001 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2002 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2004 if (color & 0xffffff) diff_count2++;
2006 else
2008 DWORD r = (color & 0xff0000) >> 16;
2009 DWORD g = (color & 0xff00) >> 8;
2010 DWORD b = (color & 0xff);
2012 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2013 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2018 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2019 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2021 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2022 MIN(diff_count, diff_count2), i1);
2024 loadpoint.x /= 2;
2025 loadpoint.y /= 2;
2026 loadrect.top /= 2;
2027 loadrect.left /= 2;
2028 loadrect.right = (loadrect.right + 1) / 2;
2029 loadrect.bottom = (loadrect.bottom + 1) / 2;
2032 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2033 * qemu Win98 / directx7 / RGB software rasterizer):
2034 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2035 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2038 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2039 for (i = 0; i < 2; i++)
2041 for (i1 = 7; i1 >= 0; i1--)
2043 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2046 memset(texture_levels, 0, sizeof(texture_levels));
2048 /* Test texture size mismatch. */
2049 for (i = 0; i < 2; i++)
2051 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2052 ddsd.dwSize = sizeof(ddsd);
2053 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2054 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2055 ddsd.dwWidth = i ? 256 : 128;
2056 ddsd.dwHeight = 128;
2057 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2058 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2059 if (FAILED(hr)) goto out;
2062 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2063 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2065 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2066 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2068 IDirectDrawSurface7_Release(texture_levels[0][0]);
2069 IDirectDrawSurface7_Release(texture_levels[1][0]);
2070 memset(texture_levels, 0, sizeof(texture_levels));
2072 memset(&d3dcaps, 0, sizeof(d3dcaps));
2073 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2074 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2076 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2078 skip("No cubemap support\n");
2080 else
2082 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2083 for (i = 0; i < 2; i++)
2085 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2086 ddsd.dwSize = sizeof(ddsd);
2087 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2088 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2089 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2090 ddsd.dwWidth = 128;
2091 ddsd.dwHeight = 128;
2092 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2093 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2094 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2095 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2096 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2097 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2098 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2099 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2100 if (FAILED(hr)) goto out;
2102 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2103 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2105 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2106 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2107 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2108 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2109 if (FAILED(hr)) goto out;
2112 for (i1 = 0; i1 < 6; i1++)
2114 /* Check the number of created mipmaps */
2115 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2116 ddsd.dwSize = sizeof(ddsd);
2117 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2118 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2119 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2120 if (U2(ddsd).dwMipMapCount != 8) goto out;
2122 for (i2 = 1; i2 < 8; i2++)
2124 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2125 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2126 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2127 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2128 if (FAILED(hr)) goto out;
2133 for (i = 0; i < 6; i++)
2134 for (i1 = 0; i1 < 8; i1++)
2136 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2137 ddsd.dwSize = sizeof(ddsd);
2138 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2139 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2140 if (FAILED(hr)) goto out;
2142 for (y = 0 ; y < ddsd.dwHeight; y++)
2144 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2146 for (x = 0; x < ddsd.dwWidth; x++)
2148 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2149 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2150 *textureRow++ = color;
2154 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2155 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2158 for (i = 0; i < 6; i++)
2159 for (i1 = 0; i1 < 8; i1++)
2161 memset(&ddbltfx, 0, sizeof(ddbltfx));
2162 ddbltfx.dwSize = sizeof(ddbltfx);
2163 U5(ddbltfx).dwFillColor = 0;
2164 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2165 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2168 loadpoint.x = loadpoint.y = 10;
2169 loadrect.left = 30;
2170 loadrect.top = 20;
2171 loadrect.right = 93;
2172 loadrect.bottom = 52;
2174 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2175 DDSCAPS2_CUBEMAP_ALLFACES);
2176 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2178 for (i = 0; i < 6; i++)
2180 loadpoint.x = loadpoint.y = 10;
2181 loadrect.left = 30;
2182 loadrect.top = 20;
2183 loadrect.right = 93;
2184 loadrect.bottom = 52;
2186 for (i1 = 0; i1 < 8; i1++)
2188 diff_count = 0;
2189 diff_count2 = 0;
2191 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2192 ddsd.dwSize = sizeof(ddsd);
2193 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2194 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2195 if (FAILED(hr)) goto out;
2197 for (y = 0 ; y < ddsd.dwHeight; y++)
2199 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2201 for (x = 0; x < ddsd.dwWidth; x++)
2203 DWORD color = *textureRow++;
2205 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2206 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2208 if (color & 0xffffff) diff_count++;
2210 else
2212 DWORD r = (color & 0xff0000) >> 16;
2213 DWORD g = (color & 0xff00) >> 8;
2214 DWORD b = (color & 0xff);
2216 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2217 b != y + loadrect.top - loadpoint.y) diff_count++;
2220 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2221 technically be correct as it's not precisely defined by docs. */
2222 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2223 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2225 if (color & 0xffffff) diff_count2++;
2227 else
2229 DWORD r = (color & 0xff0000) >> 16;
2230 DWORD g = (color & 0xff00) >> 8;
2231 DWORD b = (color & 0xff);
2233 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2234 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2239 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2240 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2242 ok(diff_count == 0 || diff_count2 == 0,
2243 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2244 MIN(diff_count, diff_count2), i, i1);
2246 loadpoint.x /= 2;
2247 loadpoint.y /= 2;
2248 loadrect.top /= 2;
2249 loadrect.left /= 2;
2250 loadrect.right = (loadrect.right + 1) / 2;
2251 loadrect.bottom = (loadrect.bottom + 1) / 2;
2255 for (i = 0; i < 2; i++)
2256 for (i1 = 5; i1 >= 0; i1--)
2257 for (i2 = 7; i2 >= 0; i2--)
2259 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2261 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2263 /* Test cubemap loading from regular texture. */
2264 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2265 ddsd.dwSize = sizeof(ddsd);
2266 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2267 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2268 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2269 ddsd.dwWidth = 128;
2270 ddsd.dwHeight = 128;
2271 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2272 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2273 if (FAILED(hr)) goto out;
2275 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2276 ddsd.dwSize = sizeof(ddsd);
2277 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2278 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2279 ddsd.dwWidth = 128;
2280 ddsd.dwHeight = 128;
2281 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2282 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2283 if (FAILED(hr)) goto out;
2285 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2286 DDSCAPS2_CUBEMAP_ALLFACES);
2287 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2289 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2290 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2291 IDirectDrawSurface7_Release(texture_levels[0][0]);
2292 memset(texture_levels, 0, sizeof(texture_levels));
2294 /* Test cubemap loading from cubemap with different number of faces. */
2295 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2296 ddsd.dwSize = sizeof(ddsd);
2297 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2298 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2299 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
2300 ddsd.dwWidth = 128;
2301 ddsd.dwHeight = 128;
2302 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2303 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2304 if (FAILED(hr)) goto out;
2306 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2307 ddsd.dwSize = sizeof(ddsd);
2308 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2309 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2310 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY;
2311 ddsd.dwWidth = 128;
2312 ddsd.dwHeight = 128;
2313 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[1][0][0], NULL);
2314 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2315 if (FAILED(hr)) goto out;
2317 /* INVALIDPARAMS tests currently would fail because wine doesn't support partial cube faces
2318 (the above created cubemaps will have all faces. */
2319 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2320 DDSCAPS2_CUBEMAP_ALLFACES);
2321 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2323 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2324 DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY);
2325 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2327 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2328 DDSCAPS2_CUBEMAP_POSITIVEX);
2329 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2331 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2332 DDSCAPS2_CUBEMAP_ALLFACES);
2333 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2335 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2336 DDSCAPS2_CUBEMAP_POSITIVEX);
2337 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2339 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2340 DDSCAPS2_CUBEMAP_POSITIVEZ);
2341 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2343 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2344 IDirectDrawSurface7_Release(cube_face_levels[1][0][0]);
2345 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2348 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2349 for (i = 0; i < 2; i++)
2351 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2352 ddsd.dwSize = sizeof(ddsd);
2353 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2354 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2355 ddsd.dwWidth = 128;
2356 ddsd.dwHeight = 128;
2357 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2358 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2359 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2360 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2361 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2362 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2363 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2364 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2365 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2366 if (FAILED(hr)) goto out;
2368 /* Check the number of created mipmaps */
2369 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2370 ddsd.dwSize = sizeof(ddsd);
2371 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2372 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2373 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2374 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2376 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2378 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2379 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2380 if (FAILED(hr)) goto out;
2384 for (i1 = 0; i1 < 8; i1++)
2386 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2387 ddsd.dwSize = sizeof(ddsd);
2388 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2389 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2390 if (FAILED(hr)) goto out;
2392 for (y = 0 ; y < ddsd.dwHeight; y++)
2394 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2396 for (x = 0; x < ddsd.dwWidth; x++)
2398 /* x stored in green component, y in blue. */
2399 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2400 *textureRow++ = color;
2404 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2405 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2408 for (i1 = 0; i1 < 4; i1++)
2410 memset(&ddbltfx, 0, sizeof(ddbltfx));
2411 ddbltfx.dwSize = sizeof(ddbltfx);
2412 U5(ddbltfx).dwFillColor = 0;
2413 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2414 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2417 loadpoint.x = loadpoint.y = 31;
2418 loadrect.left = 30;
2419 loadrect.top = 20;
2420 loadrect.right = 93;
2421 loadrect.bottom = 52;
2423 /* Destination mip levels are a subset of source mip levels. */
2424 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2425 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2427 for (i1 = 0; i1 < 4; i1++)
2429 diff_count = 0;
2430 diff_count2 = 0;
2432 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2433 ddsd.dwSize = sizeof(ddsd);
2434 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2435 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2436 if (FAILED(hr)) goto out;
2438 for (y = 0 ; y < ddsd.dwHeight; y++)
2440 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2442 for (x = 0; x < ddsd.dwWidth; x++)
2444 DWORD color = *textureRow++;
2446 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2447 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2449 if (color & 0xffffff) diff_count++;
2451 else
2453 DWORD r = (color & 0xff0000) >> 16;
2454 DWORD g = (color & 0xff00) >> 8;
2455 DWORD b = (color & 0xff);
2457 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2458 b != y + loadrect.top - loadpoint.y) diff_count++;
2461 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2462 technically be correct as it's not precisely defined by docs. */
2463 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2464 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2466 if (color & 0xffffff) diff_count2++;
2468 else
2470 DWORD r = (color & 0xff0000) >> 16;
2471 DWORD g = (color & 0xff00) >> 8;
2472 DWORD b = (color & 0xff);
2474 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2475 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2480 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2481 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2483 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2484 MIN(diff_count, diff_count2), i1);
2486 loadpoint.x /= 2;
2487 loadpoint.y /= 2;
2488 loadrect.top /= 2;
2489 loadrect.left /= 2;
2490 loadrect.right = (loadrect.right + 1) / 2;
2491 loadrect.bottom = (loadrect.bottom + 1) / 2;
2494 /* Destination mip levels are a superset of source mip levels (should fail). */
2495 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2496 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2498 for (i = 0; i < 2; i++)
2500 for (i1 = 7; i1 >= 0; i1--)
2502 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2505 memset(texture_levels, 0, sizeof(texture_levels));
2507 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2508 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2509 ddsd.dwSize = sizeof(ddsd);
2510 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2511 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2512 ddsd.dwWidth = 128;
2513 ddsd.dwHeight = 128;
2514 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2515 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2516 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2517 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2518 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2519 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2520 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2521 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2522 if (FAILED(hr)) goto out;
2524 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2525 ddsd.dwSize = sizeof(ddsd);
2526 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2527 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2528 ddsd.dwWidth = 32;
2529 ddsd.dwHeight = 32;
2530 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2531 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2532 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2533 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2534 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2535 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2536 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2537 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2538 if (FAILED(hr)) goto out;
2540 for (i1 = 1; i1 < 8; i1++)
2542 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2543 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2544 if (FAILED(hr)) goto out;
2547 for (i1 = 0; i1 < 8; i1++)
2549 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2550 ddsd.dwSize = sizeof(ddsd);
2551 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2552 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2553 if (FAILED(hr)) goto out;
2555 for (y = 0 ; y < ddsd.dwHeight; y++)
2557 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2559 for (x = 0; x < ddsd.dwWidth; x++)
2561 /* x stored in green component, y in blue. */
2562 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2563 *textureRow++ = color;
2567 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2568 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2571 memset(&ddbltfx, 0, sizeof(ddbltfx));
2572 ddbltfx.dwSize = sizeof(ddbltfx);
2573 U5(ddbltfx).dwFillColor = 0;
2574 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2575 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2577 loadpoint.x = loadpoint.y = 32;
2578 loadrect.left = 32;
2579 loadrect.top = 32;
2580 loadrect.right = 96;
2581 loadrect.bottom = 96;
2583 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2584 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2586 loadpoint.x /= 4;
2587 loadpoint.y /= 4;
2588 loadrect.top /= 4;
2589 loadrect.left /= 4;
2590 loadrect.right = (loadrect.right + 3) / 4;
2591 loadrect.bottom = (loadrect.bottom + 3) / 4;
2593 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2594 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2595 * copied subrectangles divided more than needed, without apparent logic. But it works
2596 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2597 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2598 * The following code attempts to detect broken results, actual tests will then be skipped
2600 load_mip_subset_broken = TRUE;
2601 diff_count = 0;
2603 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2604 ddsd.dwSize = sizeof(ddsd);
2605 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2606 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2607 if (FAILED(hr)) goto out;
2609 for (y = 0 ; y < ddsd.dwHeight; y++)
2611 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2613 for (x = 0; x < ddsd.dwWidth; x++)
2615 DWORD color = *textureRow++;
2617 if (x < 2 || x >= 2 + 4 ||
2618 y < 2 || y >= 2 + 4)
2620 if (color & 0xffffff) diff_count++;
2622 else
2624 DWORD r = (color & 0xff0000) >> 16;
2626 if ((r & (0xf0)) != 0xf0) diff_count++;
2631 if (diff_count) load_mip_subset_broken = FALSE;
2633 if (load_mip_subset_broken) {
2634 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2635 } else {
2636 diff_count = 0;
2638 for (y = 0 ; y < ddsd.dwHeight; y++)
2640 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2642 for (x = 0; x < ddsd.dwWidth; x++)
2644 DWORD color = *textureRow++;
2646 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2647 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2649 if (color & 0xffffff) diff_count++;
2651 else
2653 DWORD r = (color & 0xff0000) >> 16;
2654 DWORD g = (color & 0xff00) >> 8;
2655 DWORD b = (color & 0xff);
2657 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2658 b != y + loadrect.top - loadpoint.y) diff_count++;
2664 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2665 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2667 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2669 for (i = 0; i < 2; i++)
2671 for (i1 = 7; i1 >= 0; i1--)
2673 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2676 memset(texture_levels, 0, sizeof(texture_levels));
2678 if (!load_mip_subset_broken)
2680 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2681 * surface (than first source mip level)
2683 for (i = 0; i < 2; i++)
2685 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2686 ddsd.dwSize = sizeof(ddsd);
2687 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2688 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2689 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2690 ddsd.dwWidth = i ? 32 : 128;
2691 ddsd.dwHeight = i ? 32 : 128;
2692 if (i) U2(ddsd).dwMipMapCount = 4;
2693 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2694 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2695 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2696 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2697 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2698 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2699 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2700 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2701 if (FAILED(hr)) goto out;
2703 /* Check the number of created mipmaps */
2704 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2705 ddsd.dwSize = sizeof(ddsd);
2706 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2707 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2708 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2709 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2711 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2713 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2714 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2715 if (FAILED(hr)) goto out;
2719 for (i1 = 0; i1 < 8; i1++)
2721 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2722 ddsd.dwSize = sizeof(ddsd);
2723 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2724 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2725 if (FAILED(hr)) goto out;
2727 for (y = 0 ; y < ddsd.dwHeight; y++)
2729 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2731 for (x = 0; x < ddsd.dwWidth; x++)
2733 /* x stored in green component, y in blue. */
2734 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2735 *textureRow++ = color;
2739 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2740 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2743 for (i1 = 0; i1 < 4; i1++)
2745 memset(&ddbltfx, 0, sizeof(ddbltfx));
2746 ddbltfx.dwSize = sizeof(ddbltfx);
2747 U5(ddbltfx).dwFillColor = 0;
2748 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2749 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2752 loadpoint.x = loadpoint.y = 0;
2753 loadrect.left = 0;
2754 loadrect.top = 0;
2755 loadrect.right = 64;
2756 loadrect.bottom = 64;
2758 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2759 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2761 i = 0;
2762 for (i1 = 0; i1 < 8 && i < 4; i1++)
2764 DDSURFACEDESC2 ddsd2;
2766 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2767 ddsd.dwSize = sizeof(ddsd);
2768 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2769 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2771 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2772 ddsd2.dwSize = sizeof(ddsd2);
2773 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2774 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2776 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2778 diff_count = 0;
2780 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2781 ddsd.dwSize = sizeof(ddsd);
2782 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2783 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2784 if (FAILED(hr)) goto out;
2786 for (y = 0 ; y < ddsd.dwHeight; y++)
2788 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2790 for (x = 0; x < ddsd.dwWidth; x++)
2792 DWORD color = *textureRow++;
2794 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2795 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2797 if (color & 0xffffff) diff_count++;
2799 else
2801 DWORD r = (color & 0xff0000) >> 16;
2802 DWORD g = (color & 0xff00) >> 8;
2803 DWORD b = (color & 0xff);
2805 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2806 b != y + loadrect.top - loadpoint.y) diff_count++;
2811 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2812 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2814 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2816 i++;
2819 loadpoint.x /= 2;
2820 loadpoint.y /= 2;
2821 loadrect.top /= 2;
2822 loadrect.left /= 2;
2823 loadrect.right = (loadrect.right + 1) / 2;
2824 loadrect.bottom = (loadrect.bottom + 1) / 2;
2827 for (i = 0; i < 2; i++)
2829 for (i1 = 7; i1 >= 0; i1--)
2831 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2834 memset(texture_levels, 0, sizeof(texture_levels));
2837 /* Test palette copying. */
2838 for (i = 0; i < 2; i++)
2840 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2841 ddsd.dwSize = sizeof(ddsd);
2842 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2843 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2844 ddsd.dwWidth = 128;
2845 ddsd.dwHeight = 128;
2846 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2847 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2848 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2849 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2850 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2851 if (FAILED(hr)) goto out;
2853 /* Check the number of created mipmaps */
2854 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2855 ddsd.dwSize = sizeof(ddsd);
2856 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2857 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2858 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2859 if (U2(ddsd).dwMipMapCount != 8) goto out;
2861 for (i1 = 1; i1 < 8; i1++)
2863 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2864 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2865 if (FAILED(hr)) goto out;
2869 memset(table1, 0, sizeof(table1));
2870 for (i = 0; i < 3; i++)
2872 table1[0].peBlue = i + 1;
2873 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2874 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2875 if (FAILED(hr))
2877 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2878 goto out;
2882 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2883 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2885 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2886 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2888 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2889 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2891 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2892 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2893 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2894 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2896 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2897 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2899 memset(table1, 0, sizeof(table1));
2900 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2901 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2902 if (SUCCEEDED(hr))
2904 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2905 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2906 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2909 /* Test colorkey copying. */
2910 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2911 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2912 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2913 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2914 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2916 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2917 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2919 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2920 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2922 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2923 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2924 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2925 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2927 out:
2929 for (i = 0; i < 5; i++)
2931 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2934 for (i = 0; i < 2; i++)
2936 for (i1 = 7; i1 >= 0; i1--)
2938 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2942 for (i = 0; i < 2; i++)
2943 for (i1 = 5; i1 >= 0; i1--)
2944 for (i2 = 7; i2 >= 0; i2--)
2946 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2950 static void SetMaterialTest(void)
2952 HRESULT rc;
2954 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2955 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2958 static void ComputeSphereVisibility(void)
2960 D3DMATRIX proj, view, world;
2961 D3DVALUE radius[3];
2962 D3DVECTOR center[3];
2963 DWORD result[3];
2964 HRESULT rc;
2966 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
2967 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
2968 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
2969 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
2971 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
2972 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
2973 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
2974 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
2976 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
2977 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
2978 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
2979 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
2981 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
2982 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2983 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2985 U1(center[0]).x=11.461533;
2986 U2(center[0]).y=-4.761727;
2987 U3(center[0]).z=-1.171646;
2989 radius[0]=38.252632;
2991 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2993 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2994 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
2996 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
2997 radius[0]=4.354097;
2998 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
2999 radius[1]=12.500704;
3000 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
3001 radius[2]=17.251318;
3003 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
3005 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3006 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3007 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3008 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
3009 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3010 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3012 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3013 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3014 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3015 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3017 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3018 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3019 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3020 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3022 U1(center[0]).x=0.0;
3023 U2(center[0]).y=0.0;
3024 U3(center[0]).z=0.05;
3026 radius[0]=0.04;
3028 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3029 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3031 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3033 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3034 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3036 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3037 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3038 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3039 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3041 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3043 U1(center[0]).x=0.0;
3044 U2(center[0]).y=0.0;
3045 U3(center[0]).z=0.5;
3047 radius[0]=0.5;
3049 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3051 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3052 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3054 U1(center[0]).x=0.0;
3055 U2(center[0]).y=0.0;
3056 U3(center[0]).z=0.0;
3058 radius[0]=0.0;
3060 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3062 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3063 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3065 U1(center[0]).x=-1.0;
3066 U2(center[0]).y=-1.0;
3067 U3(center[0]).z=0.50;
3069 radius[0]=0.25;
3071 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3073 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3074 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3076 U1(center[0]).x=-20.0;
3077 U2(center[0]).y=0.0;
3078 U3(center[0]).z=0.50;
3080 radius[0]=3.0;
3082 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3084 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3085 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3087 U1(center[0]).x=20.0;
3088 U2(center[0]).y=0.0;
3089 U3(center[0]).z=0.50;
3091 radius[0]=3.0f;
3093 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3095 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3096 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3098 U1(center[0]).x=0.0;
3099 U2(center[0]).y=-20.0;
3100 U3(center[0]).z=0.50;
3102 radius[0]=3.0;
3104 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3106 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3107 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3109 U1(center[0]).x=0.0;
3110 U2(center[0]).y=20.0;
3111 U3(center[0]).z=0.5;
3113 radius[0]=3.0;
3115 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3117 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3118 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3120 U1(center[0]).x=0.0;
3121 U2(center[0]).y=0.0;
3122 U3(center[0]).z=-20;
3124 radius[0]=3.0;
3126 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3128 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3129 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3131 U1(center[0]).x=0.0;
3132 U2(center[0]).y=0.0;
3133 U3(center[0]).z=20.0;
3135 radius[0]=3.0;
3137 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3139 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3140 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3143 static void SetRenderTargetTest(void)
3145 HRESULT hr;
3146 IDirectDrawSurface7 *newrt, *oldrt;
3147 D3DVIEWPORT7 vp;
3148 DDSURFACEDESC2 ddsd;
3149 DWORD stateblock;
3151 memset(&ddsd, 0, sizeof(ddsd));
3152 ddsd.dwSize = sizeof(ddsd);
3153 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3154 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3155 ddsd.dwWidth = 64;
3156 ddsd.dwHeight = 64;
3157 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3158 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3159 if(FAILED(hr))
3161 skip("Skipping SetRenderTarget test\n");
3162 return;
3165 memset(&vp, 0, sizeof(vp));
3166 vp.dwX = 10;
3167 vp.dwY = 10;
3168 vp.dwWidth = 246;
3169 vp.dwHeight = 246;
3170 vp.dvMinZ = 0.25;
3171 vp.dvMaxZ = 0.75;
3172 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3173 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3175 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3176 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3178 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3179 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3180 memset(&vp, 0xff, sizeof(vp));
3181 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3182 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3183 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3184 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3185 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3186 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3187 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3188 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3190 memset(&vp, 0, sizeof(vp));
3191 vp.dwX = 0;
3192 vp.dwY = 0;
3193 vp.dwWidth = 64;
3194 vp.dwHeight = 64;
3195 vp.dvMinZ = 0.0;
3196 vp.dvMaxZ = 1.0;
3197 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3198 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3200 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3201 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3202 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3203 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3205 /* Check this twice, before and after ending the stateblock */
3206 memset(&vp, 0xff, sizeof(vp));
3207 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3208 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3209 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3210 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3211 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3212 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3213 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3214 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3216 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3217 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3219 memset(&vp, 0xff, sizeof(vp));
3220 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3221 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3222 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3223 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3224 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3225 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3226 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3227 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3229 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3230 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3232 memset(&vp, 0, sizeof(vp));
3233 vp.dwX = 0;
3234 vp.dwY = 0;
3235 vp.dwWidth = 256;
3236 vp.dwHeight = 256;
3237 vp.dvMinZ = 0.0;
3238 vp.dvMaxZ = 0.0;
3239 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3240 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3242 IDirectDrawSurface7_Release(oldrt);
3243 IDirectDrawSurface7_Release(newrt);
3246 static UINT expect_message;
3248 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3250 if (expect_message && message == expect_message) expect_message = 0;
3252 return DefWindowProcA(hwnd, message, wparam, lparam);
3255 static void test_wndproc(void)
3257 IDirectDraw7 *ddraw7;
3258 WNDCLASSA wc = {0};
3259 LONG_PTR proc;
3260 HWND window;
3261 HRESULT hr;
3262 ULONG ref;
3264 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3265 if (FAILED(hr))
3267 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3268 return;
3271 wc.lpfnWndProc = test_proc;
3272 wc.lpszClassName = "d3d7_test_wndproc_wc";
3273 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3275 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3276 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3278 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3279 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3280 (LONG_PTR)test_proc, proc);
3282 expect_message = WM_SETFOCUS;
3284 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3285 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3286 if (FAILED(hr))
3288 IDirectDraw7_Release(ddraw7);
3289 goto done;
3292 ok(!expect_message, "Expected message %#x, but didn't receive it.\n", expect_message);
3294 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3295 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3296 (LONG_PTR)test_proc, proc);
3298 ref = IDirectDraw7_Release(ddraw7);
3299 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3301 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3302 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3303 (LONG_PTR)test_proc, proc);
3305 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3306 if (FAILED(hr))
3308 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3309 return;
3312 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3313 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3314 (LONG_PTR)test_proc, proc);
3316 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3317 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3318 if (FAILED(hr))
3320 IDirectDraw7_Release(ddraw7);
3321 goto done;
3324 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3325 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3326 (LONG_PTR)test_proc, proc);
3328 ref = IDirectDraw7_Release(ddraw7);
3329 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3331 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3332 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3333 (LONG_PTR)DefWindowProcA, proc);
3335 done:
3336 expect_message = 0;
3337 DestroyWindow(window);
3338 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3341 static void VertexBufferLockRest(void)
3343 D3DVERTEXBUFFERDESC desc;
3344 IDirect3DVertexBuffer7 *buffer;
3345 HRESULT hr;
3346 unsigned int i;
3347 void *data;
3348 const struct
3350 DWORD flags;
3351 const char *debug_string;
3352 HRESULT result;
3354 test_data[] =
3356 {0, "(none)", D3D_OK },
3357 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3358 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3359 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3360 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3361 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3362 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3363 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3365 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3366 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3367 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3370 memset(&desc, 0 , sizeof(desc));
3371 desc.dwSize = sizeof(desc);
3372 desc.dwCaps = 0;
3373 desc.dwFVF = D3DFVF_XYZ;
3374 desc.dwNumVertices = 64;
3375 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3376 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3378 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3380 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3381 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3382 test_data[i].debug_string, hr, test_data[i].result);
3383 if(SUCCEEDED(hr))
3385 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3386 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3387 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3391 IDirect3DVertexBuffer7_Release(buffer);
3394 static void FindDevice(void)
3396 static const struct
3398 const GUID *guid;
3399 int todo;
3400 } deviceGUIDs[] =
3402 {&IID_IDirect3DRampDevice, 1},
3403 {&IID_IDirect3DRGBDevice},
3406 D3DFINDDEVICESEARCH search = {0};
3407 D3DFINDDEVICERESULT result = {0};
3408 HRESULT hr;
3409 int i;
3411 /* Test invalid parameters. */
3412 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3413 ok(hr == DDERR_INVALIDPARAMS,
3414 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3416 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3417 ok(hr == DDERR_INVALIDPARAMS,
3418 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3420 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3421 ok(hr == DDERR_INVALIDPARAMS,
3422 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3424 search.dwSize = 0;
3425 result.dwSize = 0;
3427 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3428 ok(hr == DDERR_INVALIDPARAMS,
3429 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3431 search.dwSize = sizeof(search) + 1;
3432 result.dwSize = sizeof(result) + 1;
3434 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3435 ok(hr == DDERR_INVALIDPARAMS,
3436 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3438 /* Specifying no flags is permitted. */
3439 search.dwSize = sizeof(search);
3440 search.dwFlags = 0;
3441 result.dwSize = sizeof(result);
3443 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3444 ok(hr == D3D_OK,
3445 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3447 /* Try an arbitrary non-device GUID. */
3448 search.dwSize = sizeof(search);
3449 search.dwFlags = D3DFDS_GUID;
3450 search.guid = IID_IDirect3D;
3451 result.dwSize = sizeof(result);
3453 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3454 ok(hr == DDERR_NOTFOUND,
3455 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3457 /* The reference device GUID can't be enumerated. */
3458 search.dwSize = sizeof(search);
3459 search.dwFlags = D3DFDS_GUID;
3460 search.guid = IID_IDirect3DRefDevice;
3461 result.dwSize = sizeof(result);
3463 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3464 todo_wine
3465 ok(hr == DDERR_NOTFOUND,
3466 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3468 /* These GUIDs appear to be always present. */
3469 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3471 search.dwSize = sizeof(search);
3472 search.dwFlags = D3DFDS_GUID;
3473 search.guid = *deviceGUIDs[i].guid;
3474 result.dwSize = sizeof(result);
3476 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3478 if (deviceGUIDs[i].todo)
3480 todo_wine
3481 ok(hr == D3D_OK,
3482 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3484 else
3486 ok(hr == D3D_OK,
3487 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3491 /* Curiously the color model criteria seem to be ignored. */
3492 search.dwSize = sizeof(search);
3493 search.dwFlags = D3DFDS_COLORMODEL;
3494 search.dcmColorModel = 0xdeadbeef;
3495 result.dwSize = sizeof(result);
3497 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3498 todo_wine
3499 ok(hr == D3D_OK,
3500 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3503 START_TEST(d3d)
3505 init_function_pointers();
3506 if(!pDirectDrawCreateEx) {
3507 win_skip("function DirectDrawCreateEx not available\n");
3508 return;
3511 if(!CreateDirect3D()) {
3512 skip("Skipping d3d7 tests\n");
3513 } else {
3514 LightTest();
3515 ProcessVerticesTest();
3516 StateTest();
3517 SceneTest();
3518 LimitTest();
3519 D3D7EnumTest();
3520 SetMaterialTest();
3521 ComputeSphereVisibility();
3522 CapsTest();
3523 VertexBufferDescTest();
3524 D3D7_OldRenderStateTest();
3525 DeviceLoadTest();
3526 SetRenderTargetTest();
3527 VertexBufferLockRest();
3528 ReleaseDirect3D();
3531 if (!D3D1_createObjects()) {
3532 skip("Skipping d3d1 tests\n");
3533 } else {
3534 Direct3D1Test();
3535 TextureLoadTest();
3536 ViewportTest();
3537 FindDevice();
3538 D3D1_releaseObjects();
3541 test_wndproc();