push 585d938e6dafa7e4b71343fb5b928a9214e5518c
[wine/hacks.git] / dlls / ddraw / tests / d3d.c
blobbf933bcfaf37dfa66b8e3344fa41aed2854b7608
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 #include <assert.h>
24 #include "wine/test.h"
25 #include "ddraw.h"
26 #include "d3d.h"
28 static LPDIRECTDRAW7 lpDD = NULL;
29 static LPDIRECT3D7 lpD3D = NULL;
30 static LPDIRECTDRAWSURFACE7 lpDDS = NULL;
31 static LPDIRECTDRAWSURFACE7 lpDDSdepth = NULL;
32 static LPDIRECT3DDEVICE7 lpD3DDevice = NULL;
33 static LPDIRECT3DVERTEXBUFFER7 lpVBufSrc = NULL;
34 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest1 = NULL;
35 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest2 = NULL;
37 static IDirectDraw *DirectDraw1 = NULL;
38 static IDirectDrawSurface *Surface1 = NULL;
39 static IDirect3D *Direct3D1 = NULL;
40 static IDirect3DDevice *Direct3DDevice1 = NULL;
41 static IDirect3DExecuteBuffer *ExecuteBuffer = NULL;
42 static IDirect3DViewport *Viewport = NULL;
44 typedef struct {
45 int total;
46 int rgb;
47 int hal;
48 int tnlhal;
49 int unk;
50 } D3D7ETest;
52 /* To compare bad floating point numbers. Not the ideal way to do it,
53 * but it should be enough for here */
54 #define comparefloat(a, b) ( (((a) - (b)) < 0.0001) && (((a) - (b)) > -0.0001) )
56 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
58 typedef struct _VERTEX
60 float x, y, z; /* position */
61 } VERTEX, *LPVERTEX;
63 typedef struct _TVERTEX
65 float x, y, z; /* position */
66 float rhw;
67 } TVERTEX, *LPTVERTEX;
70 static void init_function_pointers(void)
72 HMODULE hmod = GetModuleHandleA("ddraw.dll");
73 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
77 static BOOL CreateDirect3D(void)
79 HRESULT rc;
80 DDSURFACEDESC2 ddsd;
82 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
83 &IID_IDirectDraw7, NULL);
84 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
85 if (!lpDD) {
86 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
87 return FALSE;
90 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
91 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
93 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
94 if (rc == E_NOINTERFACE) return FALSE;
95 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
97 memset(&ddsd, 0, sizeof(ddsd));
98 ddsd.dwSize = sizeof(ddsd);
99 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
100 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
101 ddsd.dwWidth = 256;
102 ddsd.dwHeight = 256;
103 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
104 if (!SUCCEEDED(rc))
105 return FALSE;
107 memset(&ddsd, 0, sizeof(ddsd));
108 ddsd.dwSize = sizeof(ddsd);
109 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
110 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
111 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
112 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
113 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
114 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
115 ddsd.dwWidth = 256;
116 ddsd.dwHeight = 256;
117 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
118 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
119 if (!SUCCEEDED(rc)) {
120 lpDDSdepth = NULL;
121 } else {
122 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
123 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
124 if (!SUCCEEDED(rc))
125 return FALSE;
128 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
129 &lpD3DDevice);
130 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
131 if (!lpD3DDevice) {
132 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
133 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
134 &lpD3DDevice);
135 if (!lpD3DDevice) {
136 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
137 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
138 &lpD3DDevice);
139 if (!lpD3DDevice) {
140 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
141 return FALSE;
146 return TRUE;
149 static void ReleaseDirect3D(void)
151 if (lpD3DDevice != NULL)
153 IDirect3DDevice7_Release(lpD3DDevice);
154 lpD3DDevice = NULL;
157 if (lpDDSdepth != NULL)
159 IDirectDrawSurface_Release(lpDDSdepth);
160 lpDDSdepth = NULL;
163 if (lpDDS != NULL)
165 IDirectDrawSurface_Release(lpDDS);
166 lpDDS = NULL;
169 if (lpD3D != NULL)
171 IDirect3D7_Release(lpD3D);
172 lpD3D = NULL;
175 if (lpDD != NULL)
177 IDirectDraw_Release(lpDD);
178 lpDD = NULL;
182 static void LightTest(void)
184 HRESULT rc;
185 D3DLIGHT7 light;
186 D3DLIGHT7 defaultlight;
187 BOOL bEnabled = FALSE;
188 float one = 1.0f;
189 float zero= 0.0f;
190 D3DMATERIAL7 mat;
191 BOOL enabled;
192 unsigned int i;
193 D3DDEVICEDESC7 caps;
195 /* Set a few lights with funky indices. */
196 memset(&light, 0, sizeof(light));
197 light.dltType = D3DLIGHT_DIRECTIONAL;
198 U1(light.dcvDiffuse).r = 0.5f;
199 U2(light.dcvDiffuse).g = 0.6f;
200 U3(light.dcvDiffuse).b = 0.7f;
201 U2(light.dvDirection).y = 1.f;
203 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
204 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
205 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
206 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
207 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
208 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
211 /* Try to retrieve a light beyond the indices of the lights that have
212 been set. */
213 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
214 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
215 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
216 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
219 /* Try to retrieve one of the lights that have been set */
220 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
221 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
224 /* Enable a light that have been previously set. */
225 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
226 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
229 /* Enable some lights that have not been previously set, and verify that
230 they have been initialized with proper default values. */
231 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
232 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
233 U1(defaultlight.dcvDiffuse).r = 1.f;
234 U2(defaultlight.dcvDiffuse).g = 1.f;
235 U3(defaultlight.dcvDiffuse).b = 1.f;
236 U3(defaultlight.dvDirection).z = 1.f;
238 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
239 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
240 memset(&light, 0, sizeof(D3DLIGHT7));
241 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
242 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
243 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
244 "light data doesn't match expected default values\n" );
246 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
247 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
248 memset(&light, 0, sizeof(D3DLIGHT7));
249 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
250 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
251 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
252 "light data doesn't match expected default values\n" );
255 /* Disable one of the light that have been previously enabled. */
256 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
257 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
259 /* Try to retrieve the enable status of some lights */
260 /* Light 20 is supposed to be disabled */
261 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
262 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
263 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
265 /* Light 10 is supposed to be enabled */
266 bEnabled = FALSE;
267 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
268 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
269 ok(bEnabled, "GetLightEnable says the light is disabled\n");
271 /* Light 80 has not been set */
272 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
273 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
275 /* Light 23 has not been set */
276 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
277 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
279 /* Set some lights with invalid parameters */
280 memset(&light, 0, sizeof(D3DLIGHT7));
281 light.dltType = 0;
282 U1(light.dcvDiffuse).r = 1.f;
283 U2(light.dcvDiffuse).g = 1.f;
284 U3(light.dcvDiffuse).b = 1.f;
285 U3(light.dvDirection).z = 1.f;
286 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
287 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
289 memset(&light, 0, sizeof(D3DLIGHT7));
290 light.dltType = 12345;
291 U1(light.dcvDiffuse).r = 1.f;
292 U2(light.dcvDiffuse).g = 1.f;
293 U3(light.dcvDiffuse).b = 1.f;
294 U3(light.dvDirection).z = 1.f;
295 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
296 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
298 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
299 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
301 memset(&light, 0, sizeof(D3DLIGHT7));
302 light.dltType = D3DLIGHT_SPOT;
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;
308 light.dvAttenuation0 = -one / zero; /* -INFINITY */
309 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
310 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
312 light.dvAttenuation0 = -1.0;
313 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
314 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
316 light.dvAttenuation0 = 0.0;
317 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
318 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
320 light.dvAttenuation0 = 1.0;
321 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
322 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
324 light.dvAttenuation0 = one / zero; /* +INFINITY */
325 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
326 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
328 light.dvAttenuation0 = zero / zero; /* NaN */
329 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
330 ok(rc==D3D_OK ||
331 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
333 /* Directional light ignores attenuation */
334 light.dltType = D3DLIGHT_DIRECTIONAL;
335 light.dvAttenuation0 = -1.0;
336 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
337 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
339 memset(&mat, 0, sizeof(mat));
340 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
341 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
343 U4(mat).power = 129.0;
344 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
345 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
346 memset(&mat, 0, sizeof(mat));
347 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
348 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
349 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
351 U4(mat).power = -1.0;
352 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
353 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
354 memset(&mat, 0, sizeof(mat));
355 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
356 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
357 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
359 memset(&caps, 0, sizeof(caps));
360 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
361 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
363 if ( caps.dwMaxActiveLights == (DWORD) -1) {
364 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
365 skip("T&L not supported\n");
366 return;
369 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
370 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
371 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
372 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
373 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
374 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
377 /* TODO: Test the rendering results in this situation */
378 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
379 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
380 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
381 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
382 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
383 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
384 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
386 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
387 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
388 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
392 static void ProcessVerticesTest(void)
394 D3DVERTEXBUFFERDESC desc;
395 HRESULT rc;
396 VERTEX *in;
397 TVERTEX *out;
398 VERTEX *out2;
399 D3DVIEWPORT7 vp;
400 D3DMATRIX view = { 2.0, 0.0, 0.0, 0.0,
401 0.0, -1.0, 0.0, 0.0,
402 0.0, 0.0, 1.0, 0.0,
403 0.0, 0.0, 0.0, 3.0 };
405 D3DMATRIX world = { 0.0, 1.0, 0.0, 0.0,
406 1.0, 0.0, 0.0, 0.0,
407 0.0, 0.0, 0.0, 1.0,
408 0.0, 1.0, 1.0, 1.0 };
410 D3DMATRIX proj = { 1.0, 0.0, 0.0, 1.0,
411 0.0, 1.0, 1.0, 0.0,
412 0.0, 1.0, 1.0, 0.0,
413 1.0, 0.0, 0.0, 1.0 };
414 /* Create some vertex buffers */
416 memset(&desc, 0, sizeof(desc));
417 desc.dwSize = sizeof(desc);
418 desc.dwCaps = 0;
419 desc.dwFVF = D3DFVF_XYZ;
420 desc.dwNumVertices = 16;
421 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
422 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
423 if (!lpVBufSrc)
425 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
426 goto out;
429 memset(&desc, 0, sizeof(desc));
430 desc.dwSize = sizeof(desc);
431 desc.dwCaps = 0;
432 desc.dwFVF = D3DFVF_XYZRHW;
433 desc.dwNumVertices = 16;
434 /* Msdn says that the last parameter must be 0 - check that */
435 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest1, 4);
436 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
437 if (!lpVBufDest1)
439 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
440 goto out;
443 memset(&desc, 0, sizeof(desc));
444 desc.dwSize = sizeof(desc);
445 desc.dwCaps = 0;
446 desc.dwFVF = D3DFVF_XYZ;
447 desc.dwNumVertices = 16;
448 /* Msdn says that the last parameter must be 0 - check that */
449 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest2, 12345678);
450 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
451 if (!lpVBufDest2)
453 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
454 goto out;
457 rc = IDirect3DVertexBuffer7_Lock(lpVBufSrc, 0, (void **) &in, NULL);
458 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
459 if(!in) goto out;
461 /* Check basic transformation */
463 in[0].x = 0.0;
464 in[0].y = 0.0;
465 in[0].z = 0.0;
467 in[1].x = 1.0;
468 in[1].y = 1.0;
469 in[1].z = 1.0;
471 in[2].x = -1.0;
472 in[2].y = -1.0;
473 in[2].z = 0.5;
475 in[3].x = 0.5;
476 in[3].y = -0.5;
477 in[3].z = 0.25;
478 rc = IDirect3DVertexBuffer7_Unlock(lpVBufSrc);
479 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
481 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
482 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
484 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest2, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
485 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
487 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
488 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
489 if(!out) goto out;
491 /* Check the results */
492 ok( comparefloat(out[0].x, 128.0 ) &&
493 comparefloat(out[0].y, 128.0 ) &&
494 comparefloat(out[0].z, 0.0 ) &&
495 comparefloat(out[0].rhw, 1.0 ),
496 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
498 ok( comparefloat(out[1].x, 256.0 ) &&
499 comparefloat(out[1].y, 0.0 ) &&
500 comparefloat(out[1].z, 1.0 ) &&
501 comparefloat(out[1].rhw, 1.0 ),
502 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
504 ok( comparefloat(out[2].x, 0.0 ) &&
505 comparefloat(out[2].y, 256.0 ) &&
506 comparefloat(out[2].z, 0.5 ) &&
507 comparefloat(out[2].rhw, 1.0 ),
508 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
510 ok( comparefloat(out[3].x, 192.0 ) &&
511 comparefloat(out[3].y, 192.0 ) &&
512 comparefloat(out[3].z, 0.25 ) &&
513 comparefloat(out[3].rhw, 1.0 ),
514 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
516 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
517 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
518 out = NULL;
520 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest2, 0, (void **) &out2, NULL);
521 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
522 if(!out2) goto out;
523 /* Small thing without much practical meaning, but I stumbled upon it,
524 * so let's check for it: If the output vertex buffer has to RHW value,
525 * The RHW value of the last vertex is written into the next vertex
527 ok( comparefloat(out2[4].x, 1.0 ) &&
528 comparefloat(out2[4].y, 0.0 ) &&
529 comparefloat(out2[4].z, 0.0 ),
530 "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z);
532 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest2);
533 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
534 out = NULL;
536 /* Try a more complicated viewport, same vertices */
537 memset(&vp, 0, sizeof(vp));
538 vp.dwX = 10;
539 vp.dwY = 5;
540 vp.dwWidth = 246;
541 vp.dwHeight = 130;
542 vp.dvMinZ = -2.0;
543 vp.dvMaxZ = 4.0;
544 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
545 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed with rc=%x\n", rc);
547 /* Process again */
548 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
549 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
551 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
552 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
553 if(!out) goto out;
555 /* Check the results */
556 ok( comparefloat(out[0].x, 133.0 ) &&
557 comparefloat(out[0].y, 70.0 ) &&
558 comparefloat(out[0].z, -2.0 ) &&
559 comparefloat(out[0].rhw, 1.0 ),
560 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
562 ok( comparefloat(out[1].x, 256.0 ) &&
563 comparefloat(out[1].y, 5.0 ) &&
564 comparefloat(out[1].z, 4.0 ) &&
565 comparefloat(out[1].rhw, 1.0 ),
566 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
568 ok( comparefloat(out[2].x, 10.0 ) &&
569 comparefloat(out[2].y, 135.0 ) &&
570 comparefloat(out[2].z, 1.0 ) &&
571 comparefloat(out[2].rhw, 1.0 ),
572 "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
574 ok( comparefloat(out[3].x, 194.5 ) &&
575 comparefloat(out[3].y, 102.5 ) &&
576 comparefloat(out[3].z, -0.5 ) &&
577 comparefloat(out[3].rhw, 1.0 ),
578 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
580 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
581 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
582 out = NULL;
584 /* Play with some matrices. */
586 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW, &view);
587 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
589 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
590 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
592 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
593 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
595 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
596 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
598 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
599 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
600 if(!out) goto out;
602 /* Keep the viewport simpler, otherwise we get bad numbers to compare */
603 vp.dwX = 0;
604 vp.dwY = 0;
605 vp.dwWidth = 100;
606 vp.dwHeight = 100;
607 vp.dvMinZ = 1.0;
608 vp.dvMaxZ = 0.0;
609 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
610 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed\n");
612 /* Check the results */
613 ok( comparefloat(out[0].x, 256.0 ) && /* X coordinate is cut at the surface edges */
614 comparefloat(out[0].y, 70.0 ) &&
615 comparefloat(out[0].z, -2.0 ) &&
616 comparefloat(out[0].rhw, (1.0 / 3.0)),
617 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
619 ok( comparefloat(out[1].x, 256.0 ) &&
620 comparefloat(out[1].y, 78.125000 ) &&
621 comparefloat(out[1].z, -2.750000 ) &&
622 comparefloat(out[1].rhw, 0.125000 ),
623 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
625 ok( comparefloat(out[2].x, 256.0 ) &&
626 comparefloat(out[2].y, 44.000000 ) &&
627 comparefloat(out[2].z, 0.400000 ) &&
628 comparefloat(out[2].rhw, 0.400000 ),
629 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
631 ok( comparefloat(out[3].x, 256.0 ) &&
632 comparefloat(out[3].y, 81.818184 ) &&
633 comparefloat(out[3].z, -3.090909 ) &&
634 comparefloat(out[3].rhw, 0.363636 ),
635 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
637 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
638 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
639 out = NULL;
641 out:
642 IDirect3DVertexBuffer7_Release(lpVBufSrc);
643 IDirect3DVertexBuffer7_Release(lpVBufDest1);
644 IDirect3DVertexBuffer7_Release(lpVBufDest2);
647 static void StateTest( void )
649 HRESULT rc;
651 /* The msdn says its undocumented, does it return an error too? */
652 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
653 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
654 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
655 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
659 static void SceneTest(void)
661 HRESULT hr;
663 /* Test an EndScene without beginscene. Should return an error */
664 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
665 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
667 /* Test a normal BeginScene / EndScene pair, this should work */
668 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
669 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
670 if(SUCCEEDED(hr))
672 DDBLTFX fx;
673 memset(&fx, 0, sizeof(fx));
674 fx.dwSize = sizeof(fx);
676 if(lpDDSdepth) {
677 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
678 ok(hr == D3D_OK, "Depthfill failed in a BeginScene / EndScene pair\n");
679 } else {
680 skip("Depth stencil creation failed at startup, skipping\n");
682 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
683 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
686 /* Test another EndScene without having begun a new scene. Should return an error */
687 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
688 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
690 /* Two nested BeginScene and EndScene calls */
691 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
692 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
693 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
694 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
695 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
696 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
697 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
698 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
700 /* TODO: Verify that blitting works in the same way as in d3d9 */
703 static void LimitTest(void)
705 IDirectDrawSurface7 *pTexture = NULL;
706 HRESULT hr;
707 int i;
708 DDSURFACEDESC2 ddsd;
710 memset(&ddsd, 0, sizeof(ddsd));
711 ddsd.dwSize = sizeof(ddsd);
712 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
713 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
714 ddsd.dwWidth = 16;
715 ddsd.dwHeight = 16;
716 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
717 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
718 if(!pTexture) return;
720 for(i = 0; i < 8; i++) {
721 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
722 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
723 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
724 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
725 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
726 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
729 IDirectDrawSurface7_Release(pTexture);
732 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
734 UINT ver = *((UINT *) ctx);
735 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
737 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
738 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
739 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
740 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
741 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
742 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
743 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
744 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
746 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
747 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
748 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
749 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
750 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
751 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
752 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
753 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
755 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
757 /* pow2 is hardware dependent */
759 ok(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
760 "HAL Device %d hal line caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
761 ok(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
762 "HAL Device %d hal tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
763 ok((hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
764 "HAL Device %d hel line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
765 ok((hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
766 "HAL Device %d hel tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
768 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
770 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
771 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
772 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
773 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
774 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
775 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
776 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
777 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
779 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
780 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
781 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
782 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
783 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
784 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
785 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
786 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
788 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
790 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
791 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
792 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
793 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
794 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
795 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
796 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
797 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
799 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
800 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
801 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
802 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
803 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
804 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
805 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
806 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
808 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
810 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
811 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
812 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
813 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
814 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
815 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
816 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
817 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
819 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
820 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
821 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
822 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
823 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
824 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
825 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
826 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
828 else
830 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
831 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
832 else trace("hal line does NOT have pow2 set\n");
833 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
834 else trace("hal tri does NOT have pow2 set\n");
835 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
836 else trace("hel line does NOT have pow2 set\n");
837 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
838 else trace("hel tri does NOT have pow2 set\n");
840 return DDENUMRET_OK;
843 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
845 D3D7ETest *d3d7et = (D3D7ETest*)Context;
846 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
847 d3d7et->rgb++;
848 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
849 d3d7et->hal++;
850 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
851 d3d7et->tnlhal++;
852 else
853 d3d7et->unk++;
855 d3d7et->total++;
857 return DDENUMRET_OK;
861 /* Check the deviceGUID of devices enumerated by
862 IDirect3D7_EnumDevices. */
863 static void D3D7EnumTest(void)
865 D3D7ETest d3d7et;
867 if (!lpD3D) {
868 skip("No Direct3D7 interface.\n");
869 return;
872 memset(&d3d7et, 0, sizeof(d3d7et));
873 IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, (LPVOID) &d3d7et);
876 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
877 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
879 /* We make two additional assumptions. */
880 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
882 if(d3d7et.tnlhal)
883 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
885 return;
888 static void CapsTest(void)
890 IDirect3D3 *d3d3;
891 IDirect3D3 *d3d2;
892 IDirectDraw *dd1;
893 HRESULT hr;
894 UINT ver;
896 hr = DirectDrawCreate(NULL, &dd1, NULL);
897 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
898 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
899 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
900 ver = 3;
901 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
903 IDirect3D3_Release(d3d3);
904 IDirectDraw_Release(dd1);
906 hr = DirectDrawCreate(NULL, &dd1, NULL);
907 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
908 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
909 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
910 ver = 2;
911 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
913 IDirect3D2_Release(d3d2);
914 IDirectDraw_Release(dd1);
917 struct v_in {
918 float x, y, z;
920 struct v_out {
921 float x, y, z, rhw;
924 static BOOL D3D1_createObjects(void)
926 HRESULT hr;
927 DDSURFACEDESC ddsd;
928 D3DEXECUTEBUFFERDESC desc;
929 D3DVIEWPORT vp_data;
931 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
932 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
933 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
934 if (!DirectDraw1) {
935 return FALSE;
938 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
939 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
941 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
942 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
943 if (!Direct3D1) {
944 return FALSE;
947 memset(&ddsd, 0, sizeof(ddsd));
948 ddsd.dwSize = sizeof(ddsd);
949 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
950 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
951 ddsd.dwWidth = 256;
952 ddsd.dwHeight = 256;
953 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
954 if (!Surface1) {
955 skip("DDSCAPS_3DDEVICE surface not available\n");
956 return FALSE;
959 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
960 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
961 if(!Direct3DDevice1) {
962 return FALSE;
965 memset(&desc, 0, sizeof(desc));
966 desc.dwSize = sizeof(desc);
967 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
968 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
969 desc.dwBufferSize = 128;
970 desc.lpData = NULL;
971 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
972 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
973 if(!ExecuteBuffer) {
974 return FALSE;
977 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
978 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
979 if(!Viewport) {
980 return FALSE;
983 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
984 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
986 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
987 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
988 vp_data.dwSize = sizeof(vp_data);
989 vp_data.dwX = 0;
990 vp_data.dwY = 0;
991 vp_data.dwWidth = 256;
992 vp_data.dwHeight = 256;
993 vp_data.dvScaleX = 1;
994 vp_data.dvScaleY = 1;
995 vp_data.dvMaxX = 256;
996 vp_data.dvMaxY = 256;
997 vp_data.dvMinZ = 0;
998 vp_data.dvMaxZ = 1;
999 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1000 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1002 return TRUE;
1005 static void D3D1_releaseObjects(void)
1007 if (Viewport) IDirect3DViewport_Release(Viewport);
1008 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1009 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1010 if (Surface1) IDirectDrawSurface_Release(Surface1);
1011 if (Direct3D1) IDirect3D_Release(Direct3D1);
1012 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1015 #define SET_VP_DATA(vp_data) \
1016 vp_data.dwSize = sizeof(vp_data); \
1017 vp_data.dwX = 0; \
1018 vp_data.dwY = 0; \
1019 vp_data.dwWidth = 256; \
1020 vp_data.dwHeight = 256; \
1021 vp_data.dvMaxX = 256; \
1022 vp_data.dvMaxY = 256; \
1023 vp_data.dvScaleX = 5; \
1024 vp_data.dvScaleY = 5; \
1025 vp_data.dvMinZ = -25; \
1026 vp_data.dvMaxZ = 60;
1028 static void Direct3D1Test(void)
1030 HRESULT hr;
1031 D3DEXECUTEBUFFERDESC desc;
1032 D3DVIEWPORT vp_data;
1033 D3DINSTRUCTION *instr;
1034 D3DBRANCH *branch;
1035 unsigned int idx = 0;
1036 static struct v_in testverts[] = {
1037 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1038 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1040 static struct v_in cliptest[] = {
1041 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1042 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1044 static struct v_in offscreentest[] = {
1045 {128.1, 0.0, 0.0},
1047 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1048 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1049 D3DTRANSFORMDATA transformdata;
1050 DWORD i = FALSE;
1052 memset(&desc, 0, sizeof(desc));
1053 desc.dwSize = sizeof(desc);
1054 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1055 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1057 memset(desc.lpData, 0, 128);
1058 instr = desc.lpData;
1059 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1060 instr[idx].bSize = sizeof(*branch);
1061 instr[idx].wCount = 1;
1062 idx++;
1063 branch = (D3DBRANCH *) &instr[idx];
1064 branch->dwMask = 0x0;
1065 branch->dwValue = 1;
1066 branch->bNegate = TRUE;
1067 branch->dwOffset = 0;
1068 idx += (sizeof(*branch) / sizeof(*instr));
1069 instr[idx].bOpcode = D3DOP_EXIT;
1070 instr[idx].bSize = 0;
1071 instr[idx].wCount = 0;
1072 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1073 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1075 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1076 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1078 memset(&desc, 0, sizeof(desc));
1079 desc.dwSize = sizeof(desc);
1081 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1082 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1084 memset(desc.lpData, 0, 128);
1085 instr = desc.lpData;
1086 idx = 0;
1087 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1088 instr[idx].bSize = sizeof(*branch);
1089 instr[idx].wCount = 1;
1090 idx++;
1091 branch = (D3DBRANCH *) &instr[idx];
1092 branch->dwMask = 0x0;
1093 branch->dwValue = 1;
1094 branch->bNegate = TRUE;
1095 branch->dwOffset = 64;
1096 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1097 instr[0].bOpcode = D3DOP_EXIT;
1098 instr[0].bSize = 0;
1099 instr[0].wCount = 0;
1100 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1101 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1103 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1104 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1106 /* Test rendering 0 triangles */
1107 memset(&desc, 0, sizeof(desc));
1108 desc.dwSize = sizeof(desc);
1110 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1111 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1113 memset(desc.lpData, 0, 128);
1114 instr = desc.lpData;
1115 idx = 0;
1117 instr->bOpcode = D3DOP_TRIANGLE;
1118 instr->bSize = sizeof(D3DOP_TRIANGLE);
1119 instr->wCount = 0;
1120 instr = ((D3DINSTRUCTION*)(instr))+1;
1121 instr->bOpcode = D3DOP_EXIT;
1122 instr->bSize = 0;
1123 instr->wCount = 0;
1124 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1125 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1127 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1128 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1130 memset(&transformdata, 0, sizeof(transformdata));
1131 transformdata.dwSize = sizeof(transformdata);
1132 transformdata.lpIn = (void *) testverts;
1133 transformdata.dwInSize = sizeof(testverts[0]);
1134 transformdata.lpOut = out;
1135 transformdata.dwOutSize = sizeof(out[0]);
1137 transformdata.lpHOut = NULL;
1138 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1139 &transformdata, D3DTRANSFORM_UNCLIPPED,
1140 &i);
1141 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1143 transformdata.lpHOut = outH;
1144 memset(outH, 0xcc, sizeof(outH));
1145 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1146 &transformdata, D3DTRANSFORM_UNCLIPPED,
1147 &i);
1148 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1149 ok(i == 0, "Offscreen is %d\n", i);
1151 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1152 static const struct v_out cmp[] = {
1153 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1154 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1157 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1158 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1159 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1160 out[i].x, out[i].y, out[i].z, out[i].rhw,
1161 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1163 for(i = 0; i < sizeof(outH); i++) {
1164 if(((unsigned char *) outH)[i] != 0xcc) {
1165 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1166 break;
1170 SET_VP_DATA(vp_data);
1171 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1172 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1173 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1174 &transformdata, D3DTRANSFORM_UNCLIPPED,
1175 &i);
1176 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1177 ok(i == 0, "Offscreen is %d\n", i);
1179 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1180 static const struct v_out cmp[] = {
1181 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1182 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1184 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1185 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1186 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1187 out[i].x, out[i].y, out[i].z, out[i].rhw,
1188 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1191 SET_VP_DATA(vp_data);
1192 vp_data.dwX = 10;
1193 vp_data.dwY = 20;
1194 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1195 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1196 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1197 &transformdata, D3DTRANSFORM_UNCLIPPED,
1198 &i);
1199 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1200 ok(i == 0, "Offscreen is %d\n", i);
1201 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1202 static const struct v_out cmp[] = {
1203 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1204 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1206 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1207 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1208 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1209 out[i].x, out[i].y, out[i].z, out[i].rhw,
1210 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1213 memset(out, 0xcc, sizeof(out));
1214 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1215 &transformdata, D3DTRANSFORM_CLIPPED,
1216 &i);
1217 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1218 ok(i == 0, "Offscreen is %d\n", i);
1219 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1220 static const D3DHVERTEX cmpH[] = {
1221 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1222 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1223 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1225 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1226 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1227 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1228 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1229 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1231 /* No scheme has been found behind those return values. It seems to be
1232 * whatever data windows has when throwing the vertex away. Modify the
1233 * input test vertices to test this more. Depending on the input data
1234 * it can happen that the z coord gets written into y, or similar things
1236 if(0)
1238 static const struct v_out cmp[] = {
1239 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1240 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1242 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1243 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1244 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1245 out[i].x, out[i].y, out[i].z, out[i].rhw,
1246 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1249 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1250 ok(((DWORD *) out)[i] != 0xcccccccc,
1251 "Regular output DWORD %d remained untouched\n", i);
1254 transformdata.lpIn = (void *) cliptest;
1255 transformdata.dwInSize = sizeof(cliptest[0]);
1256 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1257 &transformdata, D3DTRANSFORM_CLIPPED,
1258 &i);
1259 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1260 ok(i == 0, "Offscreen is %d\n", i);
1261 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1262 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1266 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1267 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1269 ok(Flags[i] == outH[i].dwFlags,
1270 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1271 outH[i].dwFlags, Flags[i]);
1274 SET_VP_DATA(vp_data);
1275 vp_data.dwWidth = 10;
1276 vp_data.dwHeight = 1000;
1277 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1278 i = 10;
1279 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1280 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1281 &transformdata, D3DTRANSFORM_CLIPPED,
1282 &i);
1283 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1284 ok(i == 0, "Offscreen is %d\n", i);
1285 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1286 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1288 D3DCLIP_RIGHT,
1289 D3DCLIP_LEFT,
1290 D3DCLIP_RIGHT | D3DCLIP_BACK,
1291 D3DCLIP_LEFT | D3DCLIP_FRONT,
1293 ok(Flags[i] == outH[i].dwFlags,
1294 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1295 outH[i].dwFlags, Flags[i]);
1298 SET_VP_DATA(vp_data);
1299 vp_data.dwWidth = 256;
1300 vp_data.dwHeight = 256;
1301 vp_data.dvScaleX = 1;
1302 vp_data.dvScaleY = 1;
1303 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1304 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1305 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1306 &transformdata, D3DTRANSFORM_CLIPPED,
1307 &i);
1308 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1309 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1310 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1311 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1315 D3DCLIP_BACK,
1316 D3DCLIP_FRONT,
1318 ok(Flags[i] == outH[i].dwFlags,
1319 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1320 outH[i].dwFlags, Flags[i]);
1323 /* Finally try to figure out how the DWORD dwOffscreen works.
1324 * Apparently no vertex is offscreen with clipping off,
1325 * and with clipping on the offscreen flag is set if only one vertex
1326 * is transformed, and this vertex is offscreen.
1328 SET_VP_DATA(vp_data);
1329 vp_data.dwWidth = 5;
1330 vp_data.dwHeight = 5;
1331 vp_data.dvScaleX = 10000;
1332 vp_data.dvScaleY = 10000;
1333 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1334 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1335 transformdata.lpIn = cliptest;
1336 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
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);
1341 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1342 &transformdata, D3DTRANSFORM_CLIPPED,
1343 &i);
1344 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1345 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1346 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1347 &transformdata, D3DTRANSFORM_CLIPPED,
1348 &i);
1349 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1350 ok(i == 0, "Offscreen is %d\n", i);
1351 transformdata.lpIn = cliptest + 1;
1352 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1353 &transformdata, D3DTRANSFORM_CLIPPED,
1354 &i);
1355 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1356 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1358 transformdata.lpIn = (void *) offscreentest;
1359 transformdata.dwInSize = sizeof(offscreentest[0]);
1360 SET_VP_DATA(vp_data);
1361 vp_data.dwWidth = 257;
1362 vp_data.dwHeight = 257;
1363 vp_data.dvScaleX = 1;
1364 vp_data.dvScaleY = 1;
1365 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1366 i = 12345;
1367 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1368 &transformdata, D3DTRANSFORM_CLIPPED,
1369 &i);
1370 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1371 ok(i == 0, "Offscreen is %d\n", i);
1372 vp_data.dwWidth = 256;
1373 vp_data.dwHeight = 256;
1374 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1375 i = 12345;
1376 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1377 &transformdata, D3DTRANSFORM_CLIPPED,
1378 &i);
1379 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1380 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1382 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1383 &transformdata, 0,
1384 &i);
1385 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1387 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1388 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1391 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1393 int i;
1395 for (i = 0; i < 256; i++) {
1396 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1397 table1[i].peBlue != table2[i].peBlue) return FALSE;
1400 return TRUE;
1403 /* test palette handling in IDirect3DTexture_Load */
1404 static void TextureLoadTest(void)
1406 IDirectDrawSurface *TexSurface = NULL;
1407 IDirect3DTexture *Texture = NULL;
1408 IDirectDrawSurface *TexSurface2 = NULL;
1409 IDirect3DTexture *Texture2 = NULL;
1410 IDirectDrawPalette *palette = NULL;
1411 IDirectDrawPalette *palette2 = NULL;
1412 IDirectDrawPalette *palette_tmp = NULL;
1413 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1414 HRESULT hr;
1415 DDSURFACEDESC ddsd;
1416 int i;
1418 memset (&ddsd, 0, sizeof (ddsd));
1419 ddsd.dwSize = sizeof (ddsd);
1420 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1421 ddsd.dwHeight = 128;
1422 ddsd.dwWidth = 128;
1423 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1424 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1425 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1426 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1428 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1429 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1430 if (FAILED(hr)) {
1431 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1432 goto cleanup;
1435 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1436 (void *)&Texture);
1437 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1438 if (FAILED(hr)) {
1439 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1440 goto cleanup;
1443 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1444 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1445 if (FAILED(hr)) {
1446 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1447 goto cleanup;
1450 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1451 (void *)&Texture2);
1452 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1453 if (FAILED(hr)) {
1454 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1455 goto cleanup;
1458 /* test load of Texture to Texture */
1459 hr = IDirect3DTexture_Load(Texture, Texture);
1460 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1462 /* test Load when both textures have no palette */
1463 hr = IDirect3DTexture_Load(Texture2, Texture);
1464 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1466 for (i = 0; i < 256; i++) {
1467 table1[i].peRed = i;
1468 table1[i].peGreen = i;
1469 table1[i].peBlue = i;
1470 table1[i].peFlags = 0;
1473 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1474 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1475 if (FAILED(hr)) {
1476 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1477 goto cleanup;
1480 /* test Load when source texture has palette and destination has no palette */
1481 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1482 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1483 hr = IDirect3DTexture_Load(Texture2, Texture);
1484 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1486 for (i = 0; i < 256; i++) {
1487 table2[i].peRed = 255 - i;
1488 table2[i].peGreen = 255 - i;
1489 table2[i].peBlue = 255 - i;
1490 table2[i].peFlags = 0;
1493 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1494 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1495 if (FAILED(hr)) {
1496 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1497 goto cleanup;
1500 /* test Load when source has no palette and destination has a palette */
1501 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1502 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1503 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1504 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1505 hr = IDirect3DTexture_Load(Texture2, Texture);
1506 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1507 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1508 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1509 if (!palette_tmp) {
1510 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1511 goto cleanup;
1512 } else {
1513 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1514 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1515 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1516 IDirectDrawPalette_Release(palette_tmp);
1519 /* test Load when both textures have palettes */
1520 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1521 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1522 hr = IDirect3DTexture_Load(Texture2, Texture);
1523 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1524 hr = IDirect3DTexture_Load(Texture2, Texture);
1525 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1526 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1527 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1528 if (!palette_tmp) {
1529 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1530 goto cleanup;
1531 } else {
1532 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1533 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1534 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1535 IDirectDrawPalette_Release(palette_tmp);
1538 cleanup:
1540 if (palette) IDirectDrawPalette_Release(palette);
1541 if (palette2) IDirectDrawPalette_Release(palette2);
1542 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1543 if (Texture) IDirect3DTexture_Release(Texture);
1544 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1545 if (Texture2) IDirect3DTexture_Release(Texture2);
1548 static void VertexBufferDescTest(void)
1550 HRESULT rc;
1551 D3DVERTEXBUFFERDESC desc;
1552 union mem_t
1554 D3DVERTEXBUFFERDESC desc2;
1555 unsigned char buffer[512];
1556 } mem;
1558 memset(&desc, 0, sizeof(desc));
1559 desc.dwSize = sizeof(desc);
1560 desc.dwCaps = 0;
1561 desc.dwFVF = D3DFVF_XYZ;
1562 desc.dwNumVertices = 1;
1563 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1564 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1565 if (!lpVBufSrc)
1567 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1568 goto out;
1571 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1572 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1573 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1574 if(rc != D3D_OK)
1575 skip("GetVertexBuffer Failed!\n");
1576 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1577 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1578 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1579 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1580 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1582 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1583 mem.desc2.dwSize = 0;
1584 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1585 if(rc != D3D_OK)
1586 skip("GetVertexBuffer Failed!\n");
1587 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1588 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1589 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1590 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1591 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1593 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1594 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1595 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1596 if(rc != D3D_OK)
1597 skip("GetVertexBuffer Failed!\n");
1598 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1599 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1600 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1601 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1602 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1604 out:
1605 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1608 static void D3D7_OldRenderStateTest(void)
1610 HRESULT rc;
1611 DWORD val;
1613 /* Test reaction to some deprecated states in D3D7.
1615 * IDirect3DDevice7 in Wine currently relays such states to wined3d where they are do-nothing and return 0, instead
1616 * of INVALIDPARAMS. Unless an app is found which cares this is probably ok. What this test shows is that these states
1617 * need not to be handled in D3D7.
1619 todo_wine {
1620 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1621 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %08x\n", rc);
1623 rc = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1624 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %08x\n", rc);
1626 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1627 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %08x\n", rc);
1629 rc = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1630 ok(rc == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %08x\n", rc);
1634 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1635 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1637 static void DeviceLoadTest()
1639 DDSURFACEDESC2 ddsd;
1640 IDirectDrawSurface7 *texture_levels[2][8];
1641 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1642 DWORD flags;
1643 HRESULT hr;
1644 DDBLTFX ddbltfx;
1645 RECT loadrect;
1646 POINT loadpoint;
1647 int i, i1, i2;
1648 unsigned diff_count = 0, diff_count2 = 0;
1649 unsigned x, y;
1650 BOOL load_mip_subset_broken = FALSE;
1651 IDirectDrawPalette *palettes[5];
1652 PALETTEENTRY table1[256];
1653 DDCOLORKEY ddckey;
1655 /* Test loading of texture subrectangle with a mipmap surface. */
1656 memset(texture_levels, 0, sizeof(texture_levels));
1657 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1658 memset(palettes, 0, sizeof(palettes));
1660 for (i = 0; i < 2; i++)
1662 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1663 ddsd.dwSize = sizeof(ddsd);
1664 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1665 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1666 ddsd.dwWidth = 128;
1667 ddsd.dwHeight = 128;
1668 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1669 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1670 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1671 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1672 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1673 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1674 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1675 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1676 if (FAILED(hr)) goto out;
1678 /* Check the number of created mipmaps */
1679 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1680 ddsd.dwSize = sizeof(ddsd);
1681 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1682 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1683 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1684 if (U2(ddsd).dwMipMapCount != 8) goto out;
1686 for (i1 = 1; i1 < 8; i1++)
1688 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1689 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1690 if (FAILED(hr)) goto out;
1694 for (i1 = 0; i1 < 8; i1++)
1696 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1697 ddsd.dwSize = sizeof(ddsd);
1698 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1699 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1700 if (FAILED(hr)) goto out;
1702 for (y = 0 ; y < ddsd.dwHeight; y++)
1704 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1706 for (x = 0; x < ddsd.dwWidth; x++)
1708 /* x stored in green component, y in blue. */
1709 DWORD color = 0xff0000 | (x << 8) | y;
1710 *textureRow++ = color;
1714 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1715 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1718 for (i1 = 0; i1 < 8; i1++)
1720 memset(&ddbltfx, 0, sizeof(ddbltfx));
1721 ddbltfx.dwSize = sizeof(ddbltfx);
1722 U5(ddbltfx).dwFillColor = 0;
1723 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1724 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1727 /* First test some broken coordinates. */
1728 loadpoint.x = loadpoint.y = 0;
1729 loadrect.left = 0;
1730 loadrect.top = 0;
1731 loadrect.right = 0;
1732 loadrect.bottom = 0;
1733 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1734 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1736 loadpoint.x = loadpoint.y = 50;
1737 loadrect.left = 0;
1738 loadrect.top = 0;
1739 loadrect.right = 100;
1740 loadrect.bottom = 100;
1741 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1742 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1744 /* Test actual loading. */
1745 loadpoint.x = loadpoint.y = 31;
1746 loadrect.left = 30;
1747 loadrect.top = 20;
1748 loadrect.right = 93;
1749 loadrect.bottom = 52;
1751 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1752 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1754 for (i1 = 0; i1 < 8; i1++)
1756 diff_count = 0;
1757 diff_count2 = 0;
1759 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1760 ddsd.dwSize = sizeof(ddsd);
1761 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1762 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1763 if (FAILED(hr)) goto out;
1765 for (y = 0 ; y < ddsd.dwHeight; y++)
1767 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1769 for (x = 0; x < ddsd.dwWidth; x++)
1771 DWORD color = *textureRow++;
1773 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1774 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1776 if (color & 0xffffff) diff_count++;
1778 else
1780 DWORD r = (color & 0xff0000) >> 16;
1781 DWORD g = (color & 0xff00) >> 8;
1782 DWORD b = (color & 0xff);
1784 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1787 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1788 technically be correct as it's not precisely defined by docs. */
1789 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1790 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1792 if (color & 0xffffff) diff_count2++;
1794 else
1796 DWORD r = (color & 0xff0000) >> 16;
1797 DWORD g = (color & 0xff00) >> 8;
1798 DWORD b = (color & 0xff);
1800 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
1801 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
1806 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
1807 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1809 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
1810 MIN(diff_count, diff_count2), i1);
1812 loadpoint.x /= 2;
1813 loadpoint.y /= 2;
1814 loadrect.top /= 2;
1815 loadrect.left /= 2;
1816 loadrect.right = (loadrect.right + 1) / 2;
1817 loadrect.bottom = (loadrect.bottom + 1) / 2;
1820 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
1821 * qemu Win98 / directx7 / RGB software rasterizer):
1822 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
1823 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
1826 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
1827 for (i = 0; i < 2; i++)
1829 for (i1 = 7; i1 >= 0; i1--)
1831 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
1834 memset(texture_levels, 0, sizeof(texture_levels));
1836 /* Test texture size mismatch. */
1837 for (i = 0; i < 2; i++)
1839 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1840 ddsd.dwSize = sizeof(ddsd);
1841 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1842 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1843 ddsd.dwWidth = i ? 256 : 128;
1844 ddsd.dwHeight = 128;
1845 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
1846 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1847 if (FAILED(hr)) goto out;
1850 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
1851 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1853 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
1854 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1856 IDirectDrawSurface7_Release(texture_levels[0][0]);
1857 IDirectDrawSurface7_Release(texture_levels[1][0]);
1858 memset(texture_levels, 0, sizeof(texture_levels));
1860 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
1861 for (i = 0; i < 2; i++)
1863 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1864 ddsd.dwSize = sizeof(ddsd);
1865 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1866 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1867 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1868 ddsd.dwWidth = 128;
1869 ddsd.dwHeight = 128;
1870 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1871 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1872 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
1873 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
1874 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
1875 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
1876 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
1877 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1878 if (FAILED(hr)) goto out;
1880 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
1881 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
1883 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1884 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
1885 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
1886 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1887 if (FAILED(hr)) goto out;
1890 for (i1 = 0; i1 < 6; i1++)
1892 /* Check the number of created mipmaps */
1893 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1894 ddsd.dwSize = sizeof(ddsd);
1895 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
1896 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1897 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1898 if (U2(ddsd).dwMipMapCount != 8) goto out;
1900 for (i2 = 1; i2 < 8; i2++)
1902 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
1903 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
1904 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
1905 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1906 if (FAILED(hr)) goto out;
1911 for (i = 0; i < 6; i++)
1912 for (i1 = 0; i1 < 8; i1++)
1914 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1915 ddsd.dwSize = sizeof(ddsd);
1916 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1917 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1918 if (FAILED(hr)) goto out;
1920 for (y = 0 ; y < ddsd.dwHeight; y++)
1922 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1924 for (x = 0; x < ddsd.dwWidth; x++)
1926 /* face number in low 4 bits of red, x stored in green component, y in blue. */
1927 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
1928 *textureRow++ = color;
1932 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
1933 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1936 for (i = 0; i < 6; i++)
1937 for (i1 = 0; i1 < 8; i1++)
1939 memset(&ddbltfx, 0, sizeof(ddbltfx));
1940 ddbltfx.dwSize = sizeof(ddbltfx);
1941 U5(ddbltfx).dwFillColor = 0;
1942 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1943 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1946 loadpoint.x = loadpoint.y = 10;
1947 loadrect.left = 30;
1948 loadrect.top = 20;
1949 loadrect.right = 93;
1950 loadrect.bottom = 52;
1952 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
1953 DDSCAPS2_CUBEMAP_ALLFACES);
1954 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1956 for (i = 0; i < 6; i++)
1958 loadpoint.x = loadpoint.y = 10;
1959 loadrect.left = 30;
1960 loadrect.top = 20;
1961 loadrect.right = 93;
1962 loadrect.bottom = 52;
1964 for (i1 = 0; i1 < 8; i1++)
1966 diff_count = 0;
1967 diff_count2 = 0;
1969 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1970 ddsd.dwSize = sizeof(ddsd);
1971 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1972 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1973 if (FAILED(hr)) goto out;
1975 for (y = 0 ; y < ddsd.dwHeight; y++)
1977 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1979 for (x = 0; x < ddsd.dwWidth; x++)
1981 DWORD color = *textureRow++;
1983 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1984 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1986 if (color & 0xffffff) diff_count++;
1988 else
1990 DWORD r = (color & 0xff0000) >> 16;
1991 DWORD g = (color & 0xff00) >> 8;
1992 DWORD b = (color & 0xff);
1994 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
1995 b != y + loadrect.top - loadpoint.y) diff_count++;
1998 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1999 technically be correct as it's not precisely defined by docs. */
2000 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2001 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2003 if (color & 0xffffff) diff_count2++;
2005 else
2007 DWORD r = (color & 0xff0000) >> 16;
2008 DWORD g = (color & 0xff00) >> 8;
2009 DWORD b = (color & 0xff);
2011 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2012 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2017 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2018 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2020 ok(diff_count == 0 || diff_count2 == 0,
2021 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2022 MIN(diff_count, diff_count2), i, 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;
2033 for (i = 0; i < 2; i++)
2034 for (i1 = 5; i1 >= 0; i1--)
2035 for (i2 = 7; i2 >= 0; i2--)
2037 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2039 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2041 /* Test cubemap loading from regular texture. */
2042 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2043 ddsd.dwSize = sizeof(ddsd);
2044 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2045 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2046 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2047 ddsd.dwWidth = 128;
2048 ddsd.dwHeight = 128;
2049 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2050 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2051 if (FAILED(hr)) goto out;
2053 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2054 ddsd.dwSize = sizeof(ddsd);
2055 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2056 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2057 ddsd.dwWidth = 128;
2058 ddsd.dwHeight = 128;
2059 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2060 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2061 if (FAILED(hr)) goto out;
2063 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2064 DDSCAPS2_CUBEMAP_ALLFACES);
2065 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2067 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2068 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2069 IDirectDrawSurface7_Release(texture_levels[0][0]);
2070 memset(texture_levels, 0, sizeof(texture_levels));
2072 /* Test cubemap loading from cubemap with different number of faces. */
2073 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2074 ddsd.dwSize = sizeof(ddsd);
2075 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2076 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2077 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
2078 ddsd.dwWidth = 128;
2079 ddsd.dwHeight = 128;
2080 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2081 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2082 if (FAILED(hr)) goto out;
2084 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2085 ddsd.dwSize = sizeof(ddsd);
2086 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2087 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2088 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY;
2089 ddsd.dwWidth = 128;
2090 ddsd.dwHeight = 128;
2091 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[1][0][0], NULL);
2092 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2093 if (FAILED(hr)) goto out;
2095 /* INVALIDPARAMS tests currently would fail because wine doesn't support partial cube faces
2096 (the above created cubemaps will have all faces. */
2097 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2098 DDSCAPS2_CUBEMAP_ALLFACES);
2099 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2101 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2102 DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY);
2103 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2105 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2106 DDSCAPS2_CUBEMAP_POSITIVEX);
2107 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2109 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2110 DDSCAPS2_CUBEMAP_ALLFACES);
2111 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2113 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2114 DDSCAPS2_CUBEMAP_POSITIVEX);
2115 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2117 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2118 DDSCAPS2_CUBEMAP_POSITIVEZ);
2119 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2121 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2122 IDirectDrawSurface7_Release(cube_face_levels[1][0][0]);
2123 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2125 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2126 for (i = 0; i < 2; i++)
2128 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2129 ddsd.dwSize = sizeof(ddsd);
2130 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2131 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2132 ddsd.dwWidth = 128;
2133 ddsd.dwHeight = 128;
2134 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2135 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2136 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2137 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2138 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2139 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2140 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2141 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2142 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2143 if (FAILED(hr)) goto out;
2145 /* Check the number of created mipmaps */
2146 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2147 ddsd.dwSize = sizeof(ddsd);
2148 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2149 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2150 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2151 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2153 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2155 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2156 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2157 if (FAILED(hr)) goto out;
2161 for (i1 = 0; i1 < 8; i1++)
2163 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2164 ddsd.dwSize = sizeof(ddsd);
2165 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2166 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2167 if (FAILED(hr)) goto out;
2169 for (y = 0 ; y < ddsd.dwHeight; y++)
2171 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2173 for (x = 0; x < ddsd.dwWidth; x++)
2175 /* x stored in green component, y in blue. */
2176 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2177 *textureRow++ = color;
2181 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2182 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2185 for (i1 = 0; i1 < 4; i1++)
2187 memset(&ddbltfx, 0, sizeof(ddbltfx));
2188 ddbltfx.dwSize = sizeof(ddbltfx);
2189 U5(ddbltfx).dwFillColor = 0;
2190 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2191 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2194 loadpoint.x = loadpoint.y = 31;
2195 loadrect.left = 30;
2196 loadrect.top = 20;
2197 loadrect.right = 93;
2198 loadrect.bottom = 52;
2200 /* Destination mip levels are a subset of source mip levels. */
2201 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2202 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2204 for (i1 = 0; i1 < 4; i1++)
2206 diff_count = 0;
2207 diff_count2 = 0;
2209 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2210 ddsd.dwSize = sizeof(ddsd);
2211 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2212 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2213 if (FAILED(hr)) goto out;
2215 for (y = 0 ; y < ddsd.dwHeight; y++)
2217 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2219 for (x = 0; x < ddsd.dwWidth; x++)
2221 DWORD color = *textureRow++;
2223 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2224 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2226 if (color & 0xffffff) diff_count++;
2228 else
2230 DWORD r = (color & 0xff0000) >> 16;
2231 DWORD g = (color & 0xff00) >> 8;
2232 DWORD b = (color & 0xff);
2234 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2235 b != y + loadrect.top - loadpoint.y) diff_count++;
2238 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2239 technically be correct as it's not precisely defined by docs. */
2240 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2241 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2243 if (color & 0xffffff) diff_count2++;
2245 else
2247 DWORD r = (color & 0xff0000) >> 16;
2248 DWORD g = (color & 0xff00) >> 8;
2249 DWORD b = (color & 0xff);
2251 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2252 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2257 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2258 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2260 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2261 MIN(diff_count, diff_count2), i1);
2263 loadpoint.x /= 2;
2264 loadpoint.y /= 2;
2265 loadrect.top /= 2;
2266 loadrect.left /= 2;
2267 loadrect.right = (loadrect.right + 1) / 2;
2268 loadrect.bottom = (loadrect.bottom + 1) / 2;
2271 /* Destination mip levels are a superset of source mip levels (should fail). */
2272 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2273 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2275 for (i = 0; i < 2; i++)
2277 for (i1 = 7; i1 >= 0; i1--)
2279 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2282 memset(texture_levels, 0, sizeof(texture_levels));
2284 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2285 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2286 ddsd.dwSize = sizeof(ddsd);
2287 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2288 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2289 ddsd.dwWidth = 128;
2290 ddsd.dwHeight = 128;
2291 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2292 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2293 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2294 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2295 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2296 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2297 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2298 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2299 if (FAILED(hr)) goto out;
2301 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2302 ddsd.dwSize = sizeof(ddsd);
2303 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2304 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2305 ddsd.dwWidth = 32;
2306 ddsd.dwHeight = 32;
2307 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2308 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2309 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2310 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2311 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2312 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2313 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2314 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2315 if (FAILED(hr)) goto out;
2317 for (i1 = 1; i1 < 8; i1++)
2319 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2320 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2321 if (FAILED(hr)) goto out;
2324 for (i1 = 0; i1 < 8; i1++)
2326 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2327 ddsd.dwSize = sizeof(ddsd);
2328 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2329 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2330 if (FAILED(hr)) goto out;
2332 for (y = 0 ; y < ddsd.dwHeight; y++)
2334 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2336 for (x = 0; x < ddsd.dwWidth; x++)
2338 /* x stored in green component, y in blue. */
2339 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2340 *textureRow++ = color;
2344 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2345 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2348 memset(&ddbltfx, 0, sizeof(ddbltfx));
2349 ddbltfx.dwSize = sizeof(ddbltfx);
2350 U5(ddbltfx).dwFillColor = 0;
2351 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2352 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2354 loadpoint.x = loadpoint.y = 32;
2355 loadrect.left = 32;
2356 loadrect.top = 32;
2357 loadrect.right = 96;
2358 loadrect.bottom = 96;
2360 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2361 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2363 loadpoint.x /= 4;
2364 loadpoint.y /= 4;
2365 loadrect.top /= 4;
2366 loadrect.left /= 4;
2367 loadrect.right = (loadrect.right + 3) / 4;
2368 loadrect.bottom = (loadrect.bottom + 3) / 4;
2370 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2371 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2372 * copied subrectangles divided more than needed, without apparent logic. But it works
2373 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2374 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2375 * The following code attempts to detect broken results, actual tests will then be skipped
2377 load_mip_subset_broken = TRUE;
2378 diff_count = 0;
2380 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2381 ddsd.dwSize = sizeof(ddsd);
2382 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2383 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2384 if (FAILED(hr)) goto out;
2386 for (y = 0 ; y < ddsd.dwHeight; y++)
2388 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2390 for (x = 0; x < ddsd.dwWidth; x++)
2392 DWORD color = *textureRow++;
2394 if (x < 2 || x >= 2 + 4 ||
2395 y < 2 || y >= 2 + 4)
2397 if (color & 0xffffff) diff_count++;
2399 else
2401 DWORD r = (color & 0xff0000) >> 16;
2403 if ((r & (0xf0)) != 0xf0) diff_count++;
2408 if (diff_count) load_mip_subset_broken = FALSE;
2410 if (load_mip_subset_broken) {
2411 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2412 } else {
2413 diff_count = 0;
2415 for (y = 0 ; y < ddsd.dwHeight; y++)
2417 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2419 for (x = 0; x < ddsd.dwWidth; x++)
2421 DWORD color = *textureRow++;
2423 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2424 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2426 if (color & 0xffffff) diff_count++;
2428 else
2430 DWORD r = (color & 0xff0000) >> 16;
2431 DWORD g = (color & 0xff00) >> 8;
2432 DWORD b = (color & 0xff);
2434 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2435 b != y + loadrect.top - loadpoint.y) diff_count++;
2441 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2442 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2444 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2446 for (i = 0; i < 2; i++)
2448 for (i1 = 7; i1 >= 0; i1--)
2450 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2453 memset(texture_levels, 0, sizeof(texture_levels));
2455 if (!load_mip_subset_broken)
2457 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2458 * surface (than first source mip level)
2460 for (i = 0; i < 2; i++)
2462 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2463 ddsd.dwSize = sizeof(ddsd);
2464 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2465 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2466 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2467 ddsd.dwWidth = i ? 32 : 128;
2468 ddsd.dwHeight = i ? 32 : 128;
2469 if (i) U2(ddsd).dwMipMapCount = 4;
2470 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2471 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2472 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2473 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2474 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2475 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2476 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2477 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2478 if (FAILED(hr)) goto out;
2480 /* Check the number of created mipmaps */
2481 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2482 ddsd.dwSize = sizeof(ddsd);
2483 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2484 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2485 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2486 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2488 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2490 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2491 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2492 if (FAILED(hr)) goto out;
2496 for (i1 = 0; i1 < 8; i1++)
2498 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2499 ddsd.dwSize = sizeof(ddsd);
2500 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2501 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2502 if (FAILED(hr)) goto out;
2504 for (y = 0 ; y < ddsd.dwHeight; y++)
2506 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2508 for (x = 0; x < ddsd.dwWidth; x++)
2510 /* x stored in green component, y in blue. */
2511 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2512 *textureRow++ = color;
2516 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2517 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2520 for (i1 = 0; i1 < 4; i1++)
2522 memset(&ddbltfx, 0, sizeof(ddbltfx));
2523 ddbltfx.dwSize = sizeof(ddbltfx);
2524 U5(ddbltfx).dwFillColor = 0;
2525 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2526 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2529 loadpoint.x = loadpoint.y = 0;
2530 loadrect.left = 0;
2531 loadrect.top = 0;
2532 loadrect.right = 64;
2533 loadrect.bottom = 64;
2535 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2536 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2538 i = 0;
2539 for (i1 = 0; i1 < 8 && i < 4; i1++)
2541 DDSURFACEDESC2 ddsd2;
2543 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2544 ddsd.dwSize = sizeof(ddsd);
2545 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2547 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2548 ddsd2.dwSize = sizeof(ddsd2);
2549 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2551 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2553 diff_count = 0;
2555 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2556 ddsd.dwSize = sizeof(ddsd);
2557 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2558 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2559 if (FAILED(hr)) goto out;
2561 for (y = 0 ; y < ddsd.dwHeight; y++)
2563 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2565 for (x = 0; x < ddsd.dwWidth; x++)
2567 DWORD color = *textureRow++;
2569 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2570 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2572 if (color & 0xffffff) diff_count++;
2574 else
2576 DWORD r = (color & 0xff0000) >> 16;
2577 DWORD g = (color & 0xff00) >> 8;
2578 DWORD b = (color & 0xff);
2580 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2581 b != y + loadrect.top - loadpoint.y) diff_count++;
2586 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2587 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2589 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2591 i++;
2594 loadpoint.x /= 2;
2595 loadpoint.y /= 2;
2596 loadrect.top /= 2;
2597 loadrect.left /= 2;
2598 loadrect.right = (loadrect.right + 1) / 2;
2599 loadrect.bottom = (loadrect.bottom + 1) / 2;
2602 for (i = 0; i < 2; i++)
2604 for (i1 = 7; i1 >= 0; i1--)
2606 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2609 memset(texture_levels, 0, sizeof(texture_levels));
2612 /* Test palette copying. */
2613 for (i = 0; i < 2; i++)
2615 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2616 ddsd.dwSize = sizeof(ddsd);
2617 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2618 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2619 ddsd.dwWidth = 128;
2620 ddsd.dwHeight = 128;
2621 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2622 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2623 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2624 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2625 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2626 if (FAILED(hr)) goto out;
2628 /* Check the number of created mipmaps */
2629 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2630 ddsd.dwSize = sizeof(ddsd);
2631 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2632 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2633 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2634 if (U2(ddsd).dwMipMapCount != 8) goto out;
2636 for (i1 = 1; i1 < 8; i1++)
2638 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2639 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2640 if (FAILED(hr)) goto out;
2644 memset(table1, 0, sizeof(table1));
2645 for (i = 0; i < 3; i++)
2647 table1[0].peBlue = i + 1;
2648 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2649 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2650 if (FAILED(hr))
2652 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2653 goto out;
2657 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2658 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2660 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2661 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2663 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2664 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2666 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2667 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2668 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2669 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2671 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2672 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2674 memset(table1, 0, sizeof(table1));
2675 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2676 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2677 if (SUCCEEDED(hr))
2679 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2680 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2681 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2684 /* Test colorkey copying. */
2685 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2686 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2687 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2688 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2689 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2691 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2692 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2694 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2695 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2697 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2698 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2699 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2700 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2702 out:
2704 for (i = 0; i < 5; i++)
2706 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2709 for (i = 0; i < 2; i++)
2711 for (i1 = 7; i1 >= 0; i1--)
2713 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2717 for (i = 0; i < 2; i++)
2718 for (i1 = 5; i1 >= 0; i1--)
2719 for (i2 = 7; i2 >= 0; i2--)
2721 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2725 START_TEST(d3d)
2727 init_function_pointers();
2728 if(!pDirectDrawCreateEx) {
2729 skip("function DirectDrawCreateEx not available\n");
2730 return;
2733 if(!CreateDirect3D()) {
2734 skip("Skipping d3d7 tests\n");
2735 } else {
2736 LightTest();
2737 ProcessVerticesTest();
2738 StateTest();
2739 SceneTest();
2740 LimitTest();
2741 D3D7EnumTest();
2742 CapsTest();
2743 VertexBufferDescTest();
2744 D3D7_OldRenderStateTest();
2745 DeviceLoadTest();
2746 ReleaseDirect3D();
2749 if (!D3D1_createObjects()) {
2750 skip("Skipping d3d1 tests\n");
2751 } else {
2752 Direct3D1Test();
2753 TextureLoadTest();
2754 D3D1_releaseObjects();