wined3d: Use SetWindowPos() to make the focus window active.
[wine/multimedia.git] / dlls / ddraw / tests / d3d.c
blobafa1d8427f170bd23eb9e9d4eee6b5f1c82cbf4c
1 /*
2 * Some unit tests for d3d functions
4 * Copyright (C) 2005 Antoine Chavasse
5 * Copyright (C) 2006 Stefan Dösinger for CodeWeavers
6 * Copyright (C) 2008 Alexander Dorofeyev
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define COBJMACROS
25 #include <assert.h>
26 #include "wine/test.h"
27 #include "initguid.h"
28 #include "ddraw.h"
29 #include "d3d.h"
30 #include "unknwn.h"
32 static LPDIRECTDRAW7 lpDD = NULL;
33 static LPDIRECT3D7 lpD3D = NULL;
34 static LPDIRECTDRAWSURFACE7 lpDDS = NULL;
35 static LPDIRECTDRAWSURFACE7 lpDDSdepth = NULL;
36 static LPDIRECT3DDEVICE7 lpD3DDevice = NULL;
37 static LPDIRECT3DVERTEXBUFFER7 lpVBufSrc = NULL;
38 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest1 = NULL;
39 static LPDIRECT3DVERTEXBUFFER7 lpVBufDest2 = NULL;
41 static IDirectDraw *DirectDraw1 = NULL;
42 static IDirectDrawSurface *Surface1 = NULL;
43 static IDirect3D *Direct3D1 = NULL;
44 static IDirect3DDevice *Direct3DDevice1 = NULL;
45 static IDirect3DExecuteBuffer *ExecuteBuffer = NULL;
46 static IDirect3DViewport *Viewport = NULL;
47 static IDirect3DLight *Light = NULL;
49 typedef struct {
50 int total;
51 int rgb;
52 int hal;
53 int tnlhal;
54 int unk;
55 } D3D7ETest;
57 /* To compare bad floating point numbers. Not the ideal way to do it,
58 * but it should be enough for here */
59 #define comparefloat(a, b) ( (((a) - (b)) < 0.0001) && (((a) - (b)) > -0.0001) )
61 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
63 typedef struct _VERTEX
65 float x, y, z; /* position */
66 } VERTEX, *LPVERTEX;
68 typedef struct _TVERTEX
70 float x, y, z; /* position */
71 float rhw;
72 } TVERTEX, *LPTVERTEX;
75 static void init_function_pointers(void)
77 HMODULE hmod = GetModuleHandleA("ddraw.dll");
78 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
82 static ULONG getRefcount(IUnknown *iface)
84 IUnknown_AddRef(iface);
85 return IUnknown_Release(iface);
89 static BOOL CreateDirect3D(void)
91 HRESULT rc;
92 DDSURFACEDESC2 ddsd;
94 rc = pDirectDrawCreateEx(NULL, (void**)&lpDD,
95 &IID_IDirectDraw7, NULL);
96 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
97 if (!lpDD) {
98 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
99 return FALSE;
102 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
103 ok(rc==DD_OK, "SetCooperativeLevel returned: %x\n", rc);
105 rc = IDirectDraw7_QueryInterface(lpDD, &IID_IDirect3D7, (void**) &lpD3D);
106 if (rc == E_NOINTERFACE) return FALSE;
107 ok(rc==DD_OK, "QueryInterface returned: %x\n", rc);
109 memset(&ddsd, 0, sizeof(ddsd));
110 ddsd.dwSize = sizeof(ddsd);
111 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
112 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
113 ddsd.dwWidth = 256;
114 ddsd.dwHeight = 256;
115 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDS, NULL);
116 if (FAILED(rc))
117 return FALSE;
119 memset(&ddsd, 0, sizeof(ddsd));
120 ddsd.dwSize = sizeof(ddsd);
121 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
122 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
123 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
124 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
125 U1(U4(ddsd).ddpfPixelFormat).dwZBufferBitDepth = 16;
126 U3(U4(ddsd).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
127 ddsd.dwWidth = 256;
128 ddsd.dwHeight = 256;
129 rc = IDirectDraw7_CreateSurface(lpDD, &ddsd, &lpDDSdepth, NULL);
130 ok(rc==DD_OK, "CreateSurface returned: %x\n", rc);
131 if (FAILED(rc)) {
132 lpDDSdepth = NULL;
133 } else {
134 rc = IDirectDrawSurface_AddAttachedSurface(lpDDS, lpDDSdepth);
135 ok(rc == DD_OK, "IDirectDrawSurface_AddAttachedSurface returned %x\n", rc);
136 if (FAILED(rc))
137 return FALSE;
140 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DTnLHalDevice, lpDDS,
141 &lpD3DDevice);
142 ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
143 if (!lpD3DDevice) {
144 trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
145 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
146 &lpD3DDevice);
147 if (!lpD3DDevice) {
148 trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
149 rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
150 &lpD3DDevice);
151 if (!lpD3DDevice) {
152 trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
153 return FALSE;
158 return TRUE;
161 static void ReleaseDirect3D(void)
163 if (lpD3DDevice != NULL)
165 IDirect3DDevice7_Release(lpD3DDevice);
166 lpD3DDevice = NULL;
169 if (lpDDSdepth != NULL)
171 IDirectDrawSurface_Release(lpDDSdepth);
172 lpDDSdepth = NULL;
175 if (lpDDS != NULL)
177 IDirectDrawSurface_Release(lpDDS);
178 lpDDS = NULL;
181 if (lpD3D != NULL)
183 IDirect3D7_Release(lpD3D);
184 lpD3D = NULL;
187 if (lpDD != NULL)
189 IDirectDraw_Release(lpDD);
190 lpDD = NULL;
194 static void LightTest(void)
196 HRESULT rc;
197 D3DLIGHT7 light;
198 D3DLIGHT7 defaultlight;
199 BOOL bEnabled = FALSE;
200 float one = 1.0f;
201 float zero= 0.0f;
202 D3DMATERIAL7 mat;
203 BOOL enabled;
204 unsigned int i;
205 D3DDEVICEDESC7 caps;
207 /* Set a few lights with funky indices. */
208 memset(&light, 0, sizeof(light));
209 light.dltType = D3DLIGHT_DIRECTIONAL;
210 U1(light.dcvDiffuse).r = 0.5f;
211 U2(light.dcvDiffuse).g = 0.6f;
212 U3(light.dcvDiffuse).b = 0.7f;
213 U2(light.dvDirection).y = 1.f;
215 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 5, &light);
216 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
217 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 10, &light);
218 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
219 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 45, &light);
220 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
223 /* Try to retrieve a light beyond the indices of the lights that have
224 been set. */
225 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
226 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
227 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 2, &light);
228 ok(rc==DDERR_INVALIDPARAMS, "GetLight returned: %x\n", rc);
231 /* Try to retrieve one of the lights that have been set */
232 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 10, &light);
233 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
236 /* Enable a light that have been previously set. */
237 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 10, TRUE);
238 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
241 /* Enable some lights that have not been previously set, and verify that
242 they have been initialized with proper default values. */
243 memset(&defaultlight, 0, sizeof(D3DLIGHT7));
244 defaultlight.dltType = D3DLIGHT_DIRECTIONAL;
245 U1(defaultlight.dcvDiffuse).r = 1.f;
246 U2(defaultlight.dcvDiffuse).g = 1.f;
247 U3(defaultlight.dcvDiffuse).b = 1.f;
248 U3(defaultlight.dvDirection).z = 1.f;
250 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, TRUE);
251 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
252 memset(&light, 0, sizeof(D3DLIGHT7));
253 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 20, &light);
254 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
255 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
256 "light data doesn't match expected default values\n" );
258 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 50, TRUE);
259 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
260 memset(&light, 0, sizeof(D3DLIGHT7));
261 rc = IDirect3DDevice7_GetLight(lpD3DDevice, 50, &light);
262 ok(rc==D3D_OK, "GetLight returned: %x\n", rc);
263 ok(!memcmp(&light, &defaultlight, sizeof(D3DLIGHT7)),
264 "light data doesn't match expected default values\n" );
267 /* Disable one of the light that have been previously enabled. */
268 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, 20, FALSE);
269 ok(rc==D3D_OK, "LightEnable returned: %x\n", rc);
271 /* Try to retrieve the enable status of some lights */
272 /* Light 20 is supposed to be disabled */
273 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 20, &bEnabled );
274 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
275 ok(!bEnabled, "GetLightEnable says the light is enabled\n");
277 /* Light 10 is supposed to be enabled */
278 bEnabled = FALSE;
279 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 10, &bEnabled );
280 ok(rc==D3D_OK, "GetLightEnable returned: %x\n", rc);
281 ok(bEnabled, "GetLightEnable says the light is disabled\n");
283 /* Light 80 has not been set */
284 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 80, &bEnabled );
285 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
287 /* Light 23 has not been set */
288 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, 23, &bEnabled );
289 ok(rc==DDERR_INVALIDPARAMS, "GetLightEnable returned: %x\n", rc);
291 /* Set some lights with invalid parameters */
292 memset(&light, 0, sizeof(D3DLIGHT7));
293 light.dltType = 0;
294 U1(light.dcvDiffuse).r = 1.f;
295 U2(light.dcvDiffuse).g = 1.f;
296 U3(light.dcvDiffuse).b = 1.f;
297 U3(light.dvDirection).z = 1.f;
298 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 100, &light);
299 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
301 memset(&light, 0, sizeof(D3DLIGHT7));
302 light.dltType = 12345;
303 U1(light.dcvDiffuse).r = 1.f;
304 U2(light.dcvDiffuse).g = 1.f;
305 U3(light.dcvDiffuse).b = 1.f;
306 U3(light.dvDirection).z = 1.f;
307 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 101, &light);
308 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
310 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 102, NULL);
311 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
313 memset(&light, 0, sizeof(D3DLIGHT7));
314 light.dltType = D3DLIGHT_SPOT;
315 U1(light.dcvDiffuse).r = 1.f;
316 U2(light.dcvDiffuse).g = 1.f;
317 U3(light.dcvDiffuse).b = 1.f;
318 U3(light.dvDirection).z = 1.f;
320 light.dvAttenuation0 = -one / zero; /* -INFINITY */
321 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
322 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
324 light.dvAttenuation0 = -1.0;
325 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
326 ok(rc==DDERR_INVALIDPARAMS, "SetLight returned: %x\n", rc);
328 light.dvAttenuation0 = 0.0;
329 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
330 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
332 light.dvAttenuation0 = 1.0;
333 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
334 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
336 light.dvAttenuation0 = one / zero; /* +INFINITY */
337 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
338 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
340 light.dvAttenuation0 = zero / zero; /* NaN */
341 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
342 ok(rc==D3D_OK ||
343 broken(rc==DDERR_INVALIDPARAMS), "SetLight returned: %x\n", rc);
345 /* Directional light ignores attenuation */
346 light.dltType = D3DLIGHT_DIRECTIONAL;
347 light.dvAttenuation0 = -1.0;
348 rc = IDirect3DDevice7_SetLight(lpD3DDevice, 103, &light);
349 ok(rc==D3D_OK, "SetLight returned: %x\n", rc);
351 memset(&mat, 0, sizeof(mat));
352 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
353 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial returned: %x\n", rc);
355 U4(mat).power = 129.0;
356 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
357 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = 129.0) returned: %x\n", rc);
358 memset(&mat, 0, sizeof(mat));
359 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
360 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
361 ok(U4(mat).power == 129, "Returned power is %f\n", U4(mat).power);
363 U4(mat).power = -1.0;
364 rc = IDirect3DDevice7_SetMaterial(lpD3DDevice, &mat);
365 ok(rc == D3D_OK, "IDirect3DDevice7_SetMaterial(power = -1.0) returned: %x\n", rc);
366 memset(&mat, 0, sizeof(mat));
367 rc = IDirect3DDevice7_GetMaterial(lpD3DDevice, &mat);
368 ok(rc == D3D_OK, "IDirect3DDevice7_GetMaterial returned: %x\n", rc);
369 ok(U4(mat).power == -1, "Returned power is %f\n", U4(mat).power);
371 memset(&caps, 0, sizeof(caps));
372 rc = IDirect3DDevice7_GetCaps(lpD3DDevice, &caps);
373 ok(rc == D3D_OK, "IDirect3DDevice7_GetCaps failed with %x\n", rc);
375 if ( caps.dwMaxActiveLights == (DWORD) -1) {
376 /* Some cards without T&L Support return -1 (Examples: Voodoo Banshee, RivaTNT / NV4) */
377 skip("T&L not supported\n");
378 return;
381 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
382 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, TRUE);
383 ok(rc == D3D_OK, "Enabling light %u failed with %x\n", i, rc);
384 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i, &enabled);
385 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i, rc);
386 ok(enabled, "Light %d is %s\n", i, enabled ? "enabled" : "disabled");
389 /* TODO: Test the rendering results in this situation */
390 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, TRUE);
391 ok(rc == D3D_OK, "Enabling one light more than supported returned %x\n", rc);
392 rc = IDirect3DDevice7_GetLightEnable(lpD3DDevice, i + 1, &enabled);
393 ok(rc == D3D_OK, "GetLightEnable on light %u failed with %x\n", i + 1, rc);
394 ok(enabled, "Light %d is %s\n", i + 1, enabled ? "enabled" : "disabled");
395 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i + 1, FALSE);
396 ok(rc == D3D_OK, "Disabling the additional returned %x\n", rc);
398 for(i = 1; i <= caps.dwMaxActiveLights; i++) {
399 rc = IDirect3DDevice7_LightEnable(lpD3DDevice, i, FALSE);
400 ok(rc == D3D_OK, "Disabling light %u failed with %x\n", i, rc);
404 static void ProcessVerticesTest(void)
406 D3DVERTEXBUFFERDESC desc;
407 HRESULT rc;
408 VERTEX *in;
409 TVERTEX *out;
410 VERTEX *out2;
411 D3DVIEWPORT7 vp;
412 D3DMATRIX view = { 2.0, 0.0, 0.0, 0.0,
413 0.0, -1.0, 0.0, 0.0,
414 0.0, 0.0, 1.0, 0.0,
415 0.0, 0.0, 0.0, 3.0 };
417 D3DMATRIX world = { 0.0, 1.0, 0.0, 0.0,
418 1.0, 0.0, 0.0, 0.0,
419 0.0, 0.0, 0.0, 1.0,
420 0.0, 1.0, 1.0, 1.0 };
422 D3DMATRIX proj = { 1.0, 0.0, 0.0, 1.0,
423 0.0, 1.0, 1.0, 0.0,
424 0.0, 1.0, 1.0, 0.0,
425 1.0, 0.0, 0.0, 1.0 };
426 /* Create some vertex buffers */
428 memset(&desc, 0, sizeof(desc));
429 desc.dwSize = sizeof(desc);
430 desc.dwCaps = 0;
431 desc.dwFVF = D3DFVF_XYZ;
432 desc.dwNumVertices = 16;
433 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
434 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
435 if (!lpVBufSrc)
437 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
438 goto out;
441 memset(&desc, 0, sizeof(desc));
442 desc.dwSize = sizeof(desc);
443 desc.dwCaps = 0;
444 desc.dwFVF = D3DFVF_XYZRHW;
445 desc.dwNumVertices = 16;
446 /* Msdn says that the last parameter must be 0 - check that */
447 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest1, 4);
448 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
449 if (!lpVBufDest1)
451 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
452 goto out;
455 memset(&desc, 0, sizeof(desc));
456 desc.dwSize = sizeof(desc);
457 desc.dwCaps = 0;
458 desc.dwFVF = D3DFVF_XYZ;
459 desc.dwNumVertices = 16;
460 /* Msdn says that the last parameter must be 0 - check that */
461 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufDest2, 12345678);
462 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
463 if (!lpVBufDest2)
465 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
466 goto out;
469 rc = IDirect3DVertexBuffer7_Lock(lpVBufSrc, 0, (void **) &in, NULL);
470 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
471 if(!in) goto out;
473 /* Check basic transformation */
475 in[0].x = 0.0;
476 in[0].y = 0.0;
477 in[0].z = 0.0;
479 in[1].x = 1.0;
480 in[1].y = 1.0;
481 in[1].z = 1.0;
483 in[2].x = -1.0;
484 in[2].y = -1.0;
485 in[2].z = 0.5;
487 in[3].x = 0.5;
488 in[3].y = -0.5;
489 in[3].z = 0.25;
490 rc = IDirect3DVertexBuffer7_Unlock(lpVBufSrc);
491 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
493 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
494 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
496 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest2, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
497 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
499 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
500 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
501 if(!out) goto out;
503 /* Check the results */
504 ok( comparefloat(out[0].x, 128.0 ) &&
505 comparefloat(out[0].y, 128.0 ) &&
506 comparefloat(out[0].z, 0.0 ) &&
507 comparefloat(out[0].rhw, 1.0 ),
508 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
510 ok( comparefloat(out[1].x, 256.0 ) &&
511 comparefloat(out[1].y, 0.0 ) &&
512 comparefloat(out[1].z, 1.0 ) &&
513 comparefloat(out[1].rhw, 1.0 ),
514 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
516 ok( comparefloat(out[2].x, 0.0 ) &&
517 comparefloat(out[2].y, 256.0 ) &&
518 comparefloat(out[2].z, 0.5 ) &&
519 comparefloat(out[2].rhw, 1.0 ),
520 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
522 ok( comparefloat(out[3].x, 192.0 ) &&
523 comparefloat(out[3].y, 192.0 ) &&
524 comparefloat(out[3].z, 0.25 ) &&
525 comparefloat(out[3].rhw, 1.0 ),
526 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
528 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
529 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
530 out = NULL;
532 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest2, 0, (void **) &out2, NULL);
533 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
534 if(!out2) goto out;
535 /* Small thing without much practical meaning, but I stumbled upon it,
536 * so let's check for it: If the output vertex buffer has to RHW value,
537 * The RHW value of the last vertex is written into the next vertex
539 ok( comparefloat(out2[4].x, 1.0 ) &&
540 comparefloat(out2[4].y, 0.0 ) &&
541 comparefloat(out2[4].z, 0.0 ),
542 "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z);
544 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest2);
545 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
546 out = NULL;
548 /* Try a more complicated viewport, same vertices */
549 memset(&vp, 0, sizeof(vp));
550 vp.dwX = 10;
551 vp.dwY = 5;
552 vp.dwWidth = 246;
553 vp.dwHeight = 130;
554 vp.dvMinZ = -2.0;
555 vp.dvMaxZ = 4.0;
556 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
557 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed with rc=%x\n", rc);
559 /* Process again */
560 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
561 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
563 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
564 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
565 if(!out) goto out;
567 /* Check the results */
568 ok( comparefloat(out[0].x, 133.0 ) &&
569 comparefloat(out[0].y, 70.0 ) &&
570 comparefloat(out[0].z, -2.0 ) &&
571 comparefloat(out[0].rhw, 1.0 ),
572 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
574 ok( comparefloat(out[1].x, 256.0 ) &&
575 comparefloat(out[1].y, 5.0 ) &&
576 comparefloat(out[1].z, 4.0 ) &&
577 comparefloat(out[1].rhw, 1.0 ),
578 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
580 ok( comparefloat(out[2].x, 10.0 ) &&
581 comparefloat(out[2].y, 135.0 ) &&
582 comparefloat(out[2].z, 1.0 ) &&
583 comparefloat(out[2].rhw, 1.0 ),
584 "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
586 ok( comparefloat(out[3].x, 194.5 ) &&
587 comparefloat(out[3].y, 102.5 ) &&
588 comparefloat(out[3].z, -0.5 ) &&
589 comparefloat(out[3].rhw, 1.0 ),
590 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
592 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
593 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
594 out = NULL;
596 /* Play with some matrices. */
598 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW, &view);
599 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
601 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
602 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
604 rc = IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
605 ok(rc==D3D_OK, "IDirect3DDevice7_SetTransform failed\n");
607 rc = IDirect3DVertexBuffer7_ProcessVertices(lpVBufDest1, D3DVOP_TRANSFORM, 0, 4, lpVBufSrc, 0, lpD3DDevice, 0);
608 ok(rc==D3D_OK , "IDirect3DVertexBuffer::ProcessVertices returned: %x\n", rc);
610 rc = IDirect3DVertexBuffer7_Lock(lpVBufDest1, 0, (void **) &out, NULL);
611 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Lock returned: %x\n", rc);
612 if(!out) goto out;
614 /* Keep the viewport simpler, otherwise we get bad numbers to compare */
615 vp.dwX = 0;
616 vp.dwY = 0;
617 vp.dwWidth = 100;
618 vp.dwHeight = 100;
619 vp.dvMinZ = 1.0;
620 vp.dvMaxZ = 0.0;
621 rc = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
622 ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed\n");
624 /* Check the results */
625 ok( comparefloat(out[0].x, 256.0 ) && /* X coordinate is cut at the surface edges */
626 comparefloat(out[0].y, 70.0 ) &&
627 comparefloat(out[0].z, -2.0 ) &&
628 comparefloat(out[0].rhw, (1.0 / 3.0)),
629 "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw);
631 ok( comparefloat(out[1].x, 256.0 ) &&
632 comparefloat(out[1].y, 78.125000 ) &&
633 comparefloat(out[1].z, -2.750000 ) &&
634 comparefloat(out[1].rhw, 0.125000 ),
635 "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw);
637 ok( comparefloat(out[2].x, 256.0 ) &&
638 comparefloat(out[2].y, 44.000000 ) &&
639 comparefloat(out[2].z, 0.400000 ) &&
640 comparefloat(out[2].rhw, 0.400000 ),
641 "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw);
643 ok( comparefloat(out[3].x, 256.0 ) &&
644 comparefloat(out[3].y, 81.818184 ) &&
645 comparefloat(out[3].z, -3.090909 ) &&
646 comparefloat(out[3].rhw, 0.363636 ),
647 "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw);
649 rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1);
650 ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %x\n", rc);
651 out = NULL;
653 out:
654 IDirect3DVertexBuffer7_Release(lpVBufSrc);
655 IDirect3DVertexBuffer7_Release(lpVBufDest1);
656 IDirect3DVertexBuffer7_Release(lpVBufDest2);
659 static void StateTest( void )
661 HRESULT rc;
663 /* The msdn says its undocumented, does it return an error too? */
664 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, TRUE);
665 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, TRUE) returned %08x\n", rc);
666 rc = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_ZVISIBLE, FALSE);
667 ok(rc == D3D_OK, "IDirect3DDevice7_SetRenderState(D3DRENDERSTATE_ZVISIBLE, FALSE) returned %08x\n", rc);
671 static void SceneTest(void)
673 HRESULT hr;
675 /* Test an EndScene without beginscene. Should return an error */
676 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
677 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
679 /* Test a normal BeginScene / EndScene pair, this should work */
680 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
681 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
682 if(SUCCEEDED(hr))
684 DDBLTFX fx;
685 memset(&fx, 0, sizeof(fx));
686 fx.dwSize = sizeof(fx);
688 if(lpDDSdepth) {
689 hr = IDirectDrawSurface7_Blt(lpDDSdepth, NULL, NULL, NULL, DDBLT_DEPTHFILL, &fx);
690 ok(hr == D3D_OK, "Depthfill failed in a BeginScene / EndScene pair\n");
691 } else {
692 skip("Depth stencil creation failed at startup, skipping\n");
694 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
695 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
698 /* Test another EndScene without having begun a new scene. Should return an error */
699 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
700 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
702 /* Two nested BeginScene and EndScene calls */
703 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
704 ok(hr == D3D_OK, "IDirect3DDevice7_BeginScene failed with %08x\n", hr);
705 hr = IDirect3DDevice7_BeginScene(lpD3DDevice);
706 ok(hr == D3DERR_SCENE_IN_SCENE, "IDirect3DDevice7_BeginScene returned %08x\n", hr);
707 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
708 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed with %08x\n", hr);
709 hr = IDirect3DDevice7_EndScene(lpD3DDevice);
710 ok(hr == D3DERR_SCENE_NOT_IN_SCENE, "IDirect3DDevice7_EndScene returned %08x\n", hr);
712 /* TODO: Verify that blitting works in the same way as in d3d9 */
715 static void LimitTest(void)
717 IDirectDrawSurface7 *pTexture = NULL;
718 HRESULT hr;
719 int i;
720 DDSURFACEDESC2 ddsd;
722 memset(&ddsd, 0, sizeof(ddsd));
723 ddsd.dwSize = sizeof(ddsd);
724 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
725 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
726 ddsd.dwWidth = 16;
727 ddsd.dwHeight = 16;
728 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
729 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
730 if(!pTexture) return;
732 for(i = 0; i < 8; i++) {
733 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
734 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
735 hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
736 ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
737 hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
738 ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
741 IDirectDrawSurface7_Release(pTexture);
744 static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
746 UINT ver = *((UINT *) ctx);
747 if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
749 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
750 "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
751 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
752 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
753 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
754 "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
755 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
756 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
758 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
759 "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
760 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
761 "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
762 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
763 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
764 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
765 "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
767 else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
769 /* pow2 is hardware dependent */
771 ok(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
772 "HAL Device %d hal line caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
773 ok(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
774 "HAL Device %d hal tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
775 ok((hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
776 "HAL Device %d hel line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
777 ok((hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
778 "HAL Device %d hel tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
780 else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
782 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
783 "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
784 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
785 "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
786 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
787 "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
788 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
789 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
791 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
792 "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
793 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
794 "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
795 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
796 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
797 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
798 "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
800 else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
802 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
803 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
804 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
805 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
806 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
807 "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
808 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
809 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
811 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
812 "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
813 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
814 "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
815 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
816 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
817 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
818 "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
820 else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
822 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
823 "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
824 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
825 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
826 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
827 "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
828 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
829 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
831 ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
832 "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
833 ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
834 "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
835 ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
836 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
837 ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
838 "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
840 else
842 ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
843 if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
844 else trace("hal line does NOT have pow2 set\n");
845 if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
846 else trace("hal tri does NOT have pow2 set\n");
847 if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
848 else trace("hel line does NOT have pow2 set\n");
849 if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
850 else trace("hel tri does NOT have pow2 set\n");
852 return DDENUMRET_OK;
855 static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context)
857 D3D7ETest *d3d7et = Context;
858 if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
859 d3d7et->rgb++;
860 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
861 d3d7et->hal++;
862 else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
863 d3d7et->tnlhal++;
864 else
865 d3d7et->unk++;
867 d3d7et->total++;
869 return DDENUMRET_OK;
873 /* Check the deviceGUID of devices enumerated by
874 IDirect3D7_EnumDevices. */
875 static void D3D7EnumTest(void)
877 D3D7ETest d3d7et;
879 if (!lpD3D) {
880 skip("No Direct3D7 interface.\n");
881 return;
884 memset(&d3d7et, 0, sizeof(d3d7et));
885 IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
887 /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
888 ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
890 /* We make two additional assumptions. */
891 ok(d3d7et.rgb, "No RGB Device enumerated.\n");
893 if(d3d7et.tnlhal)
894 ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
897 static void CapsTest(void)
899 IDirect3D3 *d3d3;
900 IDirect3D3 *d3d2;
901 IDirectDraw *dd1;
902 HRESULT hr;
903 UINT ver;
905 hr = DirectDrawCreate(NULL, &dd1, NULL);
906 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
907 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
908 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
909 ver = 3;
910 IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
912 IDirect3D3_Release(d3d3);
913 IDirectDraw_Release(dd1);
915 hr = DirectDrawCreate(NULL, &dd1, NULL);
916 ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
917 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
918 ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
919 ver = 2;
920 IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
922 IDirect3D2_Release(d3d2);
923 IDirectDraw_Release(dd1);
926 struct v_in {
927 float x, y, z;
929 struct v_out {
930 float x, y, z, rhw;
933 static BOOL D3D1_createObjects(void)
935 HRESULT hr;
936 DDSURFACEDESC ddsd;
937 D3DEXECUTEBUFFERDESC desc;
938 D3DVIEWPORT vp_data;
940 /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
941 hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
942 ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
943 if (!DirectDraw1) {
944 return FALSE;
947 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
948 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
950 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
951 if (hr == E_NOINTERFACE) return FALSE;
952 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
953 if (!Direct3D1) {
954 return FALSE;
957 memset(&ddsd, 0, sizeof(ddsd));
958 ddsd.dwSize = sizeof(ddsd);
959 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
960 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
961 ddsd.dwWidth = 256;
962 ddsd.dwHeight = 256;
963 IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
964 if (!Surface1) {
965 skip("DDSCAPS_3DDEVICE surface not available\n");
966 return FALSE;
969 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRGBDevice, (void **) &Direct3DDevice1);
970 ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr);
971 if(!Direct3DDevice1) {
972 return FALSE;
975 memset(&desc, 0, sizeof(desc));
976 desc.dwSize = sizeof(desc);
977 desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
978 desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY;
979 desc.dwBufferSize = 128;
980 desc.lpData = NULL;
981 hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &desc, &ExecuteBuffer, NULL);
982 ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr);
983 if(!ExecuteBuffer) {
984 return FALSE;
987 hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
988 ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
989 if(!Viewport) {
990 return FALSE;
993 hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
994 ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
996 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
997 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
998 vp_data.dwSize = sizeof(vp_data);
999 vp_data.dwX = 0;
1000 vp_data.dwY = 0;
1001 vp_data.dwWidth = 256;
1002 vp_data.dwHeight = 256;
1003 vp_data.dvScaleX = 1;
1004 vp_data.dvScaleY = 1;
1005 vp_data.dvMaxX = 256;
1006 vp_data.dvMaxY = 256;
1007 vp_data.dvMinZ = 0;
1008 vp_data.dvMaxZ = 1;
1009 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1010 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1012 hr = IDirect3D_CreateLight(Direct3D1, &Light, NULL);
1013 ok(hr == D3D_OK, "IDirect3D_CreateLight failed: %08x\n", hr);
1014 if (!Light)
1015 return FALSE;
1017 return TRUE;
1020 static void D3D1_releaseObjects(void)
1022 if (Light) IDirect3DLight_Release(Light);
1023 if (Viewport) IDirect3DViewport_Release(Viewport);
1024 if (ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
1025 if (Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
1026 if (Surface1) IDirectDrawSurface_Release(Surface1);
1027 if (Direct3D1) IDirect3D_Release(Direct3D1);
1028 if (DirectDraw1) IDirectDraw_Release(DirectDraw1);
1031 static void ViewportTest(void)
1033 HRESULT hr;
1034 LPDIRECT3DVIEWPORT2 Viewport2;
1035 D3DVIEWPORT vp1_data, ret_vp1_data;
1036 D3DVIEWPORT2 vp2_data, ret_vp2_data;
1037 float infinity;
1039 *(DWORD*)&infinity = 0x7f800000;
1041 hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
1042 ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
1044 hr = IDirect3DViewport_QueryInterface(Viewport, &IID_IDirect3DViewport2, (void**) &Viewport2);
1045 ok(hr==D3D_OK, "QueryInterface returned: %x\n", hr);
1047 vp1_data.dwSize = sizeof(vp1_data);
1048 vp1_data.dwX = 0;
1049 vp1_data.dwY = 1;
1050 vp1_data.dwWidth = 256;
1051 vp1_data.dwHeight = 257;
1052 vp1_data.dvMaxX = 0;
1053 vp1_data.dvMaxY = 0;
1054 vp1_data.dvScaleX = 0;
1055 vp1_data.dvScaleY = 0;
1056 vp1_data.dvMinZ = 0.25;
1057 vp1_data.dvMaxZ = 0.75;
1059 vp2_data.dwSize = sizeof(vp2_data);
1060 vp2_data.dwX = 2;
1061 vp2_data.dwY = 3;
1062 vp2_data.dwWidth = 258;
1063 vp2_data.dwHeight = 259;
1064 vp2_data.dvClipX = 0;
1065 vp2_data.dvClipY = 0;
1066 vp2_data.dvClipWidth = 0;
1067 vp2_data.dvClipHeight = 0;
1068 vp2_data.dvMinZ = 0.1;
1069 vp2_data.dvMaxZ = 0.9;
1071 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1072 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1074 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1075 ret_vp1_data.dwSize = sizeof(vp1_data);
1077 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1078 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1080 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1081 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1082 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1083 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1084 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1085 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1086 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1087 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1088 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1089 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1091 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1092 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1094 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1095 ret_vp2_data.dwSize = sizeof(vp2_data);
1097 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1098 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1100 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1101 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1102 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1103 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1104 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1105 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1106 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1107 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1108 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1109 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1110 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1111 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1113 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1114 ret_vp1_data.dwSize = sizeof(vp1_data);
1116 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1117 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1119 ok(ret_vp1_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp2_data.dwX);
1120 ok(ret_vp1_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp2_data.dwY);
1121 ok(ret_vp1_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp2_data.dwWidth);
1122 ok(ret_vp1_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp2_data.dwHeight);
1123 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1124 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1125 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1126 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1127 todo_wine ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1128 todo_wine ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1130 hr = IDirect3DViewport2_SetViewport2(Viewport2, &vp2_data);
1131 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport2 returned %08x\n", hr);
1133 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1134 ret_vp2_data.dwSize = sizeof(vp2_data);
1136 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1137 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1139 ok(ret_vp2_data.dwX == vp2_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp2_data.dwX);
1140 ok(ret_vp2_data.dwY == vp2_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp2_data.dwY);
1141 ok(ret_vp2_data.dwWidth == vp2_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp2_data.dwWidth);
1142 ok(ret_vp2_data.dwHeight == vp2_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp2_data.dwHeight);
1143 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1144 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1145 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1146 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1147 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1148 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1149 ok(ret_vp2_data.dvMinZ == vp2_data.dvMinZ, "dvMinZ is %f, expected %f\n", ret_vp2_data.dvMinZ, vp2_data.dvMinZ);
1150 ok(ret_vp2_data.dvMaxZ == vp2_data.dvMaxZ, "dvMaxZ is %f, expected %f\n", ret_vp2_data.dvMaxZ, vp2_data.dvMaxZ);
1152 hr = IDirect3DViewport2_SetViewport(Viewport2, &vp1_data);
1153 ok(hr == D3D_OK, "IDirect3DViewport2_SetViewport returned %08x\n", hr);
1155 memset(&ret_vp1_data, 0xff, sizeof(ret_vp1_data));
1156 ret_vp1_data.dwSize = sizeof(vp1_data);
1158 hr = IDirect3DViewport2_GetViewport(Viewport2, &ret_vp1_data);
1159 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport returned %08x\n", hr);
1161 ok(ret_vp1_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp1_data.dwX, vp1_data.dwX);
1162 ok(ret_vp1_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp1_data.dwY, vp1_data.dwY);
1163 ok(ret_vp1_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp1_data.dwWidth, vp1_data.dwWidth);
1164 ok(ret_vp1_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp1_data.dwHeight, vp1_data.dwHeight);
1165 ok(ret_vp1_data.dvMaxX == vp1_data.dvMaxX, "dvMaxX is %f, expected %f\n", ret_vp1_data.dvMaxX, vp1_data.dvMaxX);
1166 ok(ret_vp1_data.dvMaxY == vp1_data.dvMaxY, "dvMaxY is %f, expected %f\n", ret_vp1_data.dvMaxY, vp1_data.dvMaxY);
1167 todo_wine ok(ret_vp1_data.dvScaleX == infinity, "dvScaleX is %f, expected %f\n", ret_vp1_data.dvScaleX, infinity);
1168 todo_wine ok(ret_vp1_data.dvScaleY == infinity, "dvScaleY is %f, expected %f\n", ret_vp1_data.dvScaleY, infinity);
1169 ok(ret_vp1_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp1_data.dvMinZ);
1170 ok(ret_vp1_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp1_data.dvMaxZ);
1172 memset(&ret_vp2_data, 0xff, sizeof(ret_vp2_data));
1173 ret_vp2_data.dwSize = sizeof(vp2_data);
1175 hr = IDirect3DViewport2_GetViewport2(Viewport2, &ret_vp2_data);
1176 ok(hr == D3D_OK, "IDirect3DViewport2_GetViewport2 returned %08x\n", hr);
1178 ok(ret_vp2_data.dwX == vp1_data.dwX, "dwX is %u, expected %u\n", ret_vp2_data.dwX, vp1_data.dwX);
1179 ok(ret_vp2_data.dwY == vp1_data.dwY, "dwY is %u, expected %u\n", ret_vp2_data.dwY, vp1_data.dwY);
1180 ok(ret_vp2_data.dwWidth == vp1_data.dwWidth, "dwWidth is %u, expected %u\n", ret_vp2_data.dwWidth, vp1_data.dwWidth);
1181 ok(ret_vp2_data.dwHeight == vp1_data.dwHeight, "dwHeight is %u, expected %u\n", ret_vp2_data.dwHeight, vp1_data.dwHeight);
1182 ok(ret_vp2_data.dvClipX == vp2_data.dvClipX, "dvClipX is %f, expected %f\n", ret_vp2_data.dvClipX, vp2_data.dvClipX);
1183 ok(ret_vp2_data.dvClipY == vp2_data.dvClipY, "dvClipY is %f, expected %f\n", ret_vp2_data.dvClipY, vp2_data.dvClipY);
1184 ok(ret_vp2_data.dvClipWidth == vp2_data.dvClipWidth, "dvClipWidth is %f, expected %f\n",
1185 ret_vp2_data.dvClipWidth, vp2_data.dvClipWidth);
1186 ok(ret_vp2_data.dvClipHeight == vp2_data.dvClipHeight, "dvClipHeight is %f, expected %f\n",
1187 ret_vp2_data.dvClipHeight, vp2_data.dvClipHeight);
1188 ok(ret_vp2_data.dvMinZ == 0.0, "dvMinZ is %f, expected 0.0\n", ret_vp2_data.dvMinZ);
1189 ok(ret_vp2_data.dvMaxZ == 1.0, "dvMaxZ is %f, expected 1.0\n", ret_vp2_data.dvMaxZ);
1191 IDirect3DViewport2_Release(Viewport2);
1193 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1194 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1197 #define SET_VP_DATA(vp_data) \
1198 vp_data.dwSize = sizeof(vp_data); \
1199 vp_data.dwX = 0; \
1200 vp_data.dwY = 0; \
1201 vp_data.dwWidth = 256; \
1202 vp_data.dwHeight = 256; \
1203 vp_data.dvMaxX = 256; \
1204 vp_data.dvMaxY = 256; \
1205 vp_data.dvScaleX = 5; \
1206 vp_data.dvScaleY = 5; \
1207 vp_data.dvMinZ = -25; \
1208 vp_data.dvMaxZ = 60;
1210 static void Direct3D1Test(void)
1212 HRESULT hr;
1213 D3DEXECUTEBUFFERDESC desc;
1214 D3DVIEWPORT vp_data;
1215 D3DINSTRUCTION *instr;
1216 D3DBRANCH *branch;
1217 IDirect3D *Direct3D_alt;
1218 IDirect3DLight *d3dlight;
1219 ULONG refcount;
1220 unsigned int idx = 0;
1221 static struct v_in testverts[] = {
1222 {0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
1223 {0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
1225 static struct v_in cliptest[] = {
1226 {25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
1227 {25.61, 25.61, 1.01}, {-25.61, -25.61, -0.01},
1229 static struct v_in offscreentest[] = {
1230 {128.1, 0.0, 0.0},
1232 struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
1233 D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
1234 D3DTRANSFORMDATA transformdata;
1235 DWORD i = FALSE;
1237 /* Interface consistency check. */
1238 hr = IDirect3DDevice_GetDirect3D(Direct3DDevice1, &Direct3D_alt);
1239 ok(hr == D3D_OK, "IDirect3DDevice_GetDirect3D failed: %08x\n", hr);
1240 if (hr == D3D_OK)
1241 ok(Direct3D_alt == Direct3D1, "Direct3D1 struct pointer missmatch: %p != %p\n", Direct3D_alt, Direct3D1);
1243 memset(&desc, 0, sizeof(desc));
1244 desc.dwSize = sizeof(desc);
1245 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1246 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1248 memset(desc.lpData, 0, 128);
1249 instr = desc.lpData;
1250 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1251 instr[idx].bSize = sizeof(*branch);
1252 instr[idx].wCount = 1;
1253 idx++;
1254 branch = (D3DBRANCH *) &instr[idx];
1255 branch->dwMask = 0x0;
1256 branch->dwValue = 1;
1257 branch->bNegate = TRUE;
1258 branch->dwOffset = 0;
1259 idx += (sizeof(*branch) / sizeof(*instr));
1260 instr[idx].bOpcode = D3DOP_EXIT;
1261 instr[idx].bSize = 0;
1262 instr[idx].wCount = 0;
1263 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1264 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1266 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1267 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1269 memset(&desc, 0, sizeof(desc));
1270 desc.dwSize = sizeof(desc);
1272 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1273 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1275 memset(desc.lpData, 0, 128);
1276 instr = desc.lpData;
1277 idx = 0;
1278 instr[idx].bOpcode = D3DOP_BRANCHFORWARD;
1279 instr[idx].bSize = sizeof(*branch);
1280 instr[idx].wCount = 1;
1281 idx++;
1282 branch = (D3DBRANCH *) &instr[idx];
1283 branch->dwMask = 0x0;
1284 branch->dwValue = 1;
1285 branch->bNegate = TRUE;
1286 branch->dwOffset = 64;
1287 instr = (D3DINSTRUCTION*)((char*)desc.lpData + 64);
1288 instr[0].bOpcode = D3DOP_EXIT;
1289 instr[0].bSize = 0;
1290 instr[0].wCount = 0;
1291 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1292 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1294 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1295 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1297 /* Test rendering 0 triangles */
1298 memset(&desc, 0, sizeof(desc));
1299 desc.dwSize = sizeof(desc);
1301 hr = IDirect3DExecuteBuffer_Lock(ExecuteBuffer, &desc);
1302 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr);
1304 memset(desc.lpData, 0, 128);
1305 instr = desc.lpData;
1306 idx = 0;
1308 instr->bOpcode = D3DOP_TRIANGLE;
1309 instr->bSize = sizeof(D3DOP_TRIANGLE);
1310 instr->wCount = 0;
1311 instr++;
1312 instr->bOpcode = D3DOP_EXIT;
1313 instr->bSize = 0;
1314 instr->wCount = 0;
1315 hr = IDirect3DExecuteBuffer_Unlock(ExecuteBuffer);
1316 ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr);
1318 hr = IDirect3DDevice_Execute(Direct3DDevice1, ExecuteBuffer, Viewport, D3DEXECUTE_CLIPPED);
1319 ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
1321 memset(&transformdata, 0, sizeof(transformdata));
1322 transformdata.dwSize = sizeof(transformdata);
1323 transformdata.lpIn = testverts;
1324 transformdata.dwInSize = sizeof(testverts[0]);
1325 transformdata.lpOut = out;
1326 transformdata.dwOutSize = sizeof(out[0]);
1328 transformdata.lpHOut = NULL;
1329 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1330 &transformdata, D3DTRANSFORM_UNCLIPPED,
1331 &i);
1332 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1334 transformdata.lpHOut = outH;
1335 memset(outH, 0xcc, sizeof(outH));
1336 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1337 &transformdata, D3DTRANSFORM_UNCLIPPED,
1338 &i);
1339 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1340 ok(i == 0, "Offscreen is %d\n", i);
1342 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1343 static const struct v_out cmp[] = {
1344 {128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
1345 {128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
1348 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1349 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1350 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1351 out[i].x, out[i].y, out[i].z, out[i].rhw,
1352 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1354 for(i = 0; i < sizeof(outH); i++) {
1355 if(((unsigned char *) outH)[i] != 0xcc) {
1356 ok(FALSE, "Homogeneous output was generated despite UNCLIPPED flag\n");
1357 break;
1361 SET_VP_DATA(vp_data);
1362 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1363 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1364 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1365 &transformdata, D3DTRANSFORM_UNCLIPPED,
1366 &i);
1367 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1368 ok(i == 0, "Offscreen is %d\n", i);
1370 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1371 static const struct v_out cmp[] = {
1372 {128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
1373 {130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
1375 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1376 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1377 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1378 out[i].x, out[i].y, out[i].z, out[i].rhw,
1379 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1382 SET_VP_DATA(vp_data);
1383 vp_data.dwX = 10;
1384 vp_data.dwY = 20;
1385 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1386 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1387 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1388 &transformdata, D3DTRANSFORM_UNCLIPPED,
1389 &i);
1390 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1391 ok(i == 0, "Offscreen is %d\n", i);
1392 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1393 static const struct v_out cmp[] = {
1394 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
1395 {140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
1397 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1398 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1399 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1400 out[i].x, out[i].y, out[i].z, out[i].rhw,
1401 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1404 memset(out, 0xcc, sizeof(out));
1405 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1406 &transformdata, D3DTRANSFORM_CLIPPED,
1407 &i);
1408 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1409 ok(i == 0, "Offscreen is %d\n", i);
1410 for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
1411 static const D3DHVERTEX cmpH[] = {
1412 {0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
1413 {D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
1414 {D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
1416 ok(U1(cmpH[i]).hx == U1(outH[i]).hx && U2(cmpH[i]).hy == U2(outH[i]).hy &&
1417 U3(cmpH[i]).hz == U3(outH[i]).hz && cmpH[i].dwFlags == outH[i].dwFlags,
1418 "HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
1419 outH[i].dwFlags, U1(outH[i]).hx, U2(outH[i]).hy, U3(outH[i]).hz,
1420 cmpH[i].dwFlags, U1(cmpH[i]).hx, U2(cmpH[i]).hy, U3(cmpH[i]).hz);
1422 /* No scheme has been found behind those return values. It seems to be
1423 * whatever data windows has when throwing the vertex away. Modify the
1424 * input test vertices to test this more. Depending on the input data
1425 * it can happen that the z coord gets written into y, or similar things
1427 if(0)
1429 static const struct v_out cmp[] = {
1430 {138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
1431 {140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
1433 ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
1434 cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
1435 "Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
1436 out[i].x, out[i].y, out[i].z, out[i].rhw,
1437 cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
1440 for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
1441 ok(((DWORD *) out)[i] != 0xcccccccc,
1442 "Regular output DWORD %d remained untouched\n", i);
1445 transformdata.lpIn = cliptest;
1446 transformdata.dwInSize = sizeof(cliptest[0]);
1447 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1448 &transformdata, D3DTRANSFORM_CLIPPED,
1449 &i);
1450 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1451 ok(i == 0, "Offscreen is %d\n", i);
1452 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1453 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1457 D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
1458 D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
1460 ok(Flags[i] == outH[i].dwFlags,
1461 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1462 outH[i].dwFlags, Flags[i]);
1465 SET_VP_DATA(vp_data);
1466 vp_data.dwWidth = 10;
1467 vp_data.dwHeight = 1000;
1468 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1469 i = 10;
1470 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1471 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1472 &transformdata, D3DTRANSFORM_CLIPPED,
1473 &i);
1474 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1475 ok(i == 0, "Offscreen is %d\n", i);
1476 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1477 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1479 D3DCLIP_RIGHT,
1480 D3DCLIP_LEFT,
1481 D3DCLIP_RIGHT | D3DCLIP_BACK,
1482 D3DCLIP_LEFT | D3DCLIP_FRONT,
1484 ok(Flags[i] == outH[i].dwFlags,
1485 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1486 outH[i].dwFlags, Flags[i]);
1489 SET_VP_DATA(vp_data);
1490 vp_data.dwWidth = 256;
1491 vp_data.dwHeight = 256;
1492 vp_data.dvScaleX = 1;
1493 vp_data.dvScaleY = 1;
1494 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1495 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1496 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(cliptest) / sizeof(cliptest[0]),
1497 &transformdata, D3DTRANSFORM_CLIPPED,
1498 &i);
1499 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1500 ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
1501 for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
1502 DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
1506 D3DCLIP_BACK,
1507 D3DCLIP_FRONT,
1509 ok(Flags[i] == outH[i].dwFlags,
1510 "Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
1511 outH[i].dwFlags, Flags[i]);
1514 /* Finally try to figure out how the DWORD dwOffscreen works.
1515 * Apparently no vertex is offscreen with clipping off,
1516 * and with clipping on the offscreen flag is set if only one vertex
1517 * is transformed, and this vertex is offscreen.
1519 SET_VP_DATA(vp_data);
1520 vp_data.dwWidth = 5;
1521 vp_data.dwHeight = 5;
1522 vp_data.dvScaleX = 10000;
1523 vp_data.dvScaleY = 10000;
1524 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1525 ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
1526 transformdata.lpIn = cliptest;
1527 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1528 &transformdata, D3DTRANSFORM_UNCLIPPED,
1529 &i);
1530 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1531 ok(i == 0, "Offscreen is %d\n", i);
1532 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1533 &transformdata, D3DTRANSFORM_CLIPPED,
1534 &i);
1535 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1536 ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
1537 hr = IDirect3DViewport_TransformVertices(Viewport, 2,
1538 &transformdata, D3DTRANSFORM_CLIPPED,
1539 &i);
1540 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1541 ok(i == 0, "Offscreen is %d\n", i);
1542 transformdata.lpIn = cliptest + 1;
1543 hr = IDirect3DViewport_TransformVertices(Viewport, 1,
1544 &transformdata, D3DTRANSFORM_CLIPPED,
1545 &i);
1546 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1547 ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
1549 transformdata.lpIn = offscreentest;
1550 transformdata.dwInSize = sizeof(offscreentest[0]);
1551 SET_VP_DATA(vp_data);
1552 vp_data.dwWidth = 257;
1553 vp_data.dwHeight = 257;
1554 vp_data.dvScaleX = 1;
1555 vp_data.dvScaleY = 1;
1556 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1557 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1558 i = 12345;
1559 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1560 &transformdata, D3DTRANSFORM_CLIPPED,
1561 &i);
1562 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1563 ok(i == 0, "Offscreen is %d\n", i);
1564 vp_data.dwWidth = 256;
1565 vp_data.dwHeight = 256;
1566 hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
1567 ok(SUCCEEDED(hr), "IDirect3DViewport_SetViewport returned %#x.\n", hr);
1568 i = 12345;
1569 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(offscreentest) / sizeof(offscreentest[0]),
1570 &transformdata, D3DTRANSFORM_CLIPPED,
1571 &i);
1572 ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1573 ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
1575 hr = IDirect3DViewport_TransformVertices(Viewport, sizeof(testverts) / sizeof(testverts[0]),
1576 &transformdata, 0,
1577 &i);
1578 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
1580 hr = IDirect3DDevice_DeleteViewport(Direct3DDevice1, Viewport);
1581 ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
1583 hr = IDirect3DViewport_AddLight(Viewport, Light);
1584 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1585 refcount = getRefcount((IUnknown*) Light);
1586 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1588 hr = IDirect3DViewport_NextLight(Viewport, NULL, &d3dlight, D3DNEXT_HEAD);
1589 ok(hr == D3D_OK, "IDirect3DViewport_AddLight returned %08x\n", hr);
1590 ok(d3dlight == Light, "Got different light returned %p, expected %p\n", d3dlight, Light);
1591 refcount = getRefcount((IUnknown*) Light);
1592 ok(refcount == 3, "Refcount should be 2, returned is %d\n", refcount);
1594 hr = IDirect3DViewport_DeleteLight(Viewport, Light);
1595 ok(hr == D3D_OK, "IDirect3DViewport_DeleteLight returned %08x\n", hr);
1596 refcount = getRefcount((IUnknown*) Light);
1597 ok(refcount == 2, "Refcount should be 2, returned is %d\n", refcount);
1599 IDirect3DLight_Release(Light);
1602 static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY table2[256])
1604 int i;
1606 for (i = 0; i < 256; i++) {
1607 if (table1[i].peRed != table2[i].peRed || table1[i].peGreen != table2[i].peGreen ||
1608 table1[i].peBlue != table2[i].peBlue) return FALSE;
1611 return TRUE;
1614 /* test palette handling in IDirect3DTexture_Load */
1615 static void TextureLoadTest(void)
1617 IDirectDrawSurface *TexSurface = NULL;
1618 IDirect3DTexture *Texture = NULL;
1619 IDirectDrawSurface *TexSurface2 = NULL;
1620 IDirect3DTexture *Texture2 = NULL;
1621 IDirectDrawPalette *palette = NULL;
1622 IDirectDrawPalette *palette2 = NULL;
1623 IDirectDrawPalette *palette_tmp = NULL;
1624 PALETTEENTRY table1[256], table2[256], table_tmp[256];
1625 HRESULT hr;
1626 DDSURFACEDESC ddsd;
1627 int i;
1629 memset (&ddsd, 0, sizeof (ddsd));
1630 ddsd.dwSize = sizeof (ddsd);
1631 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1632 ddsd.dwHeight = 128;
1633 ddsd.dwWidth = 128;
1634 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1635 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1636 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1637 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1639 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface, NULL);
1640 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1641 if (FAILED(hr)) {
1642 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1643 goto cleanup;
1646 hr = IDirectDrawSurface_QueryInterface(TexSurface, &IID_IDirect3DTexture,
1647 (void *)&Texture);
1648 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1649 if (FAILED(hr)) {
1650 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1651 goto cleanup;
1654 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &TexSurface2, NULL);
1655 ok(hr==D3D_OK, "CreateSurface returned: %x\n", hr);
1656 if (FAILED(hr)) {
1657 skip("IDirectDraw_CreateSurface failed; skipping further tests\n");
1658 goto cleanup;
1661 hr = IDirectDrawSurface_QueryInterface(TexSurface2, &IID_IDirect3DTexture,
1662 (void *)&Texture2);
1663 ok(hr==D3D_OK, "IDirectDrawSurface_QueryInterface returned: %x\n", hr);
1664 if (FAILED(hr)) {
1665 skip("Can't get IDirect3DTexture interface; skipping further tests\n");
1666 goto cleanup;
1669 /* test load of Texture to Texture */
1670 hr = IDirect3DTexture_Load(Texture, Texture);
1671 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1673 /* test Load when both textures have no palette */
1674 hr = IDirect3DTexture_Load(Texture2, Texture);
1675 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1677 for (i = 0; i < 256; i++) {
1678 table1[i].peRed = i;
1679 table1[i].peGreen = i;
1680 table1[i].peBlue = i;
1681 table1[i].peFlags = 0;
1684 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palette, NULL);
1685 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1686 if (FAILED(hr)) {
1687 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1688 goto cleanup;
1691 /* test Load when source texture has palette and destination has no palette */
1692 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1693 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1694 hr = IDirect3DTexture_Load(Texture2, Texture);
1695 ok(hr == DDERR_NOPALETTEATTACHED, "IDirect3DTexture_Load returned %08x\n", hr);
1697 for (i = 0; i < 256; i++) {
1698 table2[i].peRed = 255 - i;
1699 table2[i].peGreen = 255 - i;
1700 table2[i].peBlue = 255 - i;
1701 table2[i].peFlags = 0;
1704 hr = IDirectDraw_CreatePalette(DirectDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table2, &palette2, NULL);
1705 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
1706 if (FAILED(hr)) {
1707 skip("IDirectDraw_CreatePalette failed; skipping further tests\n");
1708 goto cleanup;
1711 /* test Load when source has no palette and destination has a palette */
1712 hr = IDirectDrawSurface_SetPalette(TexSurface, NULL);
1713 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1714 hr = IDirectDrawSurface_SetPalette(TexSurface2, palette2);
1715 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1716 hr = IDirect3DTexture_Load(Texture2, Texture);
1717 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1718 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1719 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1720 if (!palette_tmp) {
1721 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1722 goto cleanup;
1723 } else {
1724 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1725 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1726 ok(colortables_check_equality(table2, table_tmp), "Unexpected palettized texture color table\n");
1727 IDirectDrawPalette_Release(palette_tmp);
1730 /* test Load when both textures have palettes */
1731 hr = IDirectDrawSurface_SetPalette(TexSurface, palette);
1732 ok(hr == DD_OK, "IDirectDrawSurface_SetPalette returned %08x\n", hr);
1733 hr = IDirect3DTexture_Load(Texture2, Texture);
1734 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1735 hr = IDirect3DTexture_Load(Texture2, Texture);
1736 ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr);
1737 hr = IDirectDrawSurface_GetPalette(TexSurface2, &palette_tmp);
1738 ok(hr == DD_OK, "IDirectDrawSurface_GetPalette returned %08x\n", hr);
1739 if (!palette_tmp) {
1740 skip("IDirectDrawSurface_GetPalette failed; skipping color table check\n");
1741 goto cleanup;
1742 } else {
1743 hr = IDirectDrawPalette_GetEntries(palette_tmp, 0, 0, 256, table_tmp);
1744 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
1745 ok(colortables_check_equality(table1, table_tmp), "Unexpected palettized texture color table\n");
1746 IDirectDrawPalette_Release(palette_tmp);
1749 cleanup:
1751 if (palette) IDirectDrawPalette_Release(palette);
1752 if (palette2) IDirectDrawPalette_Release(palette2);
1753 if (TexSurface) IDirectDrawSurface_Release(TexSurface);
1754 if (Texture) IDirect3DTexture_Release(Texture);
1755 if (TexSurface2) IDirectDrawSurface_Release(TexSurface2);
1756 if (Texture2) IDirect3DTexture_Release(Texture2);
1759 static void VertexBufferDescTest(void)
1761 HRESULT rc;
1762 D3DVERTEXBUFFERDESC desc;
1763 union mem_t
1765 D3DVERTEXBUFFERDESC desc2;
1766 unsigned char buffer[512];
1767 } mem;
1769 memset(&desc, 0, sizeof(desc));
1770 desc.dwSize = sizeof(desc);
1771 desc.dwCaps = 0;
1772 desc.dwFVF = D3DFVF_XYZ;
1773 desc.dwNumVertices = 1;
1774 rc = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &lpVBufSrc, 0);
1775 ok(rc==D3D_OK || rc==E_OUTOFMEMORY, "CreateVertexBuffer returned: %x\n", rc);
1776 if (!lpVBufSrc)
1778 trace("IDirect3D7::CreateVertexBuffer() failed with an error %x\n", rc);
1779 goto out;
1782 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1783 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC)*2;
1784 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1785 if(rc != D3D_OK)
1786 skip("GetVertexBuffer Failed!\n");
1787 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC)*2, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1788 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was double the size of the struct)\n");
1789 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1790 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1791 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1793 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1794 mem.desc2.dwSize = 0;
1795 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1796 if(rc != D3D_OK)
1797 skip("GetVertexBuffer Failed!\n");
1798 ok( mem.desc2.dwSize == 0, "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1799 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was 0)\n");
1800 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1801 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1802 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1804 memset(mem.buffer, 0x12, sizeof(mem.buffer));
1805 mem.desc2.dwSize = sizeof(D3DVERTEXBUFFERDESC);
1806 rc = IDirect3DVertexBuffer7_GetVertexBufferDesc(lpVBufSrc, &mem.desc2);
1807 if(rc != D3D_OK)
1808 skip("GetVertexBuffer Failed!\n");
1809 ok( mem.desc2.dwSize == sizeof(D3DVERTEXBUFFERDESC), "Size returned from GetVertexBufferDesc does not match the value put in\n" );
1810 ok( mem.buffer[sizeof(D3DVERTEXBUFFERDESC)] == 0x12, "GetVertexBufferDesc cleared outside of the struct! (dwSize was the size of the struct)\n");
1811 ok( mem.desc2.dwCaps == desc.dwCaps, "dwCaps returned differs. Got %x, expected %x\n", mem.desc2.dwCaps, desc.dwCaps);
1812 ok( mem.desc2.dwFVF == desc.dwFVF, "dwFVF returned differs. Got %x, expected %x\n", mem.desc2.dwFVF, desc.dwFVF);
1813 ok (mem.desc2.dwNumVertices == desc.dwNumVertices, "dwNumVertices returned differs. Got %x, expected %x\n", mem.desc2.dwNumVertices, desc.dwNumVertices);
1815 out:
1816 IDirect3DVertexBuffer7_Release(lpVBufSrc);
1819 static void D3D7_OldRenderStateTest(void)
1821 HRESULT hr;
1822 DWORD val;
1824 /* Test reaction to some deprecated states in D3D7. */
1825 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, 0);
1826 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1827 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREHANDLE, &val);
1828 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1829 hr = IDirect3DDevice7_SetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
1830 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_SetRenderState returned %#x.\n", hr);
1831 hr = IDirect3DDevice7_GetRenderState(lpD3DDevice, D3DRENDERSTATE_TEXTUREMAPBLEND, &val);
1832 ok(hr == DDERR_INVALIDPARAMS, "IDirect3DDevice7_GetRenderState returned %#x.\n", hr);
1835 #define IS_VALUE_NEAR(a, b) ( ((a) == (b)) || ((a) == (b) - 1) || ((a) == (b) + 1) )
1836 #define MIN(a, b) ((a) < (b) ? (a) : (b))
1838 static void DeviceLoadTest(void)
1840 DDSURFACEDESC2 ddsd;
1841 IDirectDrawSurface7 *texture_levels[2][8];
1842 IDirectDrawSurface7 *cube_face_levels[2][6][8];
1843 DWORD flags;
1844 HRESULT hr;
1845 DDBLTFX ddbltfx;
1846 RECT loadrect;
1847 POINT loadpoint;
1848 int i, i1, i2;
1849 unsigned diff_count = 0, diff_count2 = 0;
1850 unsigned x, y;
1851 BOOL load_mip_subset_broken = FALSE;
1852 IDirectDrawPalette *palettes[5];
1853 PALETTEENTRY table1[256];
1854 DDCOLORKEY ddckey;
1855 D3DDEVICEDESC7 d3dcaps;
1857 /* Test loading of texture subrectangle with a mipmap surface. */
1858 memset(texture_levels, 0, sizeof(texture_levels));
1859 memset(cube_face_levels, 0, sizeof(cube_face_levels));
1860 memset(palettes, 0, sizeof(palettes));
1862 for (i = 0; i < 2; i++)
1864 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1865 ddsd.dwSize = sizeof(ddsd);
1866 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1867 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
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, &texture_levels[i][0], NULL);
1877 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1878 if (FAILED(hr)) goto out;
1880 /* Check the number of created mipmaps */
1881 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1882 ddsd.dwSize = sizeof(ddsd);
1883 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
1884 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
1885 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
1886 if (U2(ddsd).dwMipMapCount != 8) goto out;
1888 for (i1 = 1; i1 < 8; i1++)
1890 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
1891 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1892 if (FAILED(hr)) goto out;
1896 for (i1 = 0; i1 < 8; i1++)
1898 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1899 ddsd.dwSize = sizeof(ddsd);
1900 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1901 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1902 if (FAILED(hr)) goto out;
1904 for (y = 0 ; y < ddsd.dwHeight; y++)
1906 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1908 for (x = 0; x < ddsd.dwWidth; x++)
1910 /* x stored in green component, y in blue. */
1911 DWORD color = 0xff0000 | (x << 8) | y;
1912 *textureRow++ = color;
1916 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
1917 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
1920 for (i1 = 0; i1 < 8; i1++)
1922 memset(&ddbltfx, 0, sizeof(ddbltfx));
1923 ddbltfx.dwSize = sizeof(ddbltfx);
1924 U5(ddbltfx).dwFillColor = 0;
1925 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
1926 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
1929 /* First test some broken coordinates. */
1930 loadpoint.x = loadpoint.y = 0;
1931 loadrect.left = 0;
1932 loadrect.top = 0;
1933 loadrect.right = 0;
1934 loadrect.bottom = 0;
1935 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1936 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1938 loadpoint.x = loadpoint.y = 50;
1939 loadrect.left = 0;
1940 loadrect.top = 0;
1941 loadrect.right = 100;
1942 loadrect.bottom = 100;
1943 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1944 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
1946 /* Test actual loading. */
1947 loadpoint.x = loadpoint.y = 31;
1948 loadrect.left = 30;
1949 loadrect.top = 20;
1950 loadrect.right = 93;
1951 loadrect.bottom = 52;
1953 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
1954 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
1956 for (i1 = 0; i1 < 8; i1++)
1958 diff_count = 0;
1959 diff_count2 = 0;
1961 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
1962 ddsd.dwSize = sizeof(ddsd);
1963 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
1964 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
1965 if (FAILED(hr)) goto out;
1967 for (y = 0 ; y < ddsd.dwHeight; y++)
1969 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
1971 for (x = 0; x < ddsd.dwWidth; x++)
1973 DWORD color = *textureRow++;
1975 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1976 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
1978 if (color & 0xffffff) diff_count++;
1980 else
1982 DWORD r = (color & 0xff0000) >> 16;
1983 DWORD g = (color & 0xff00) >> 8;
1984 DWORD b = (color & 0xff);
1986 if (r != 0xff || g != x + loadrect.left - loadpoint.x || b != y + loadrect.top - loadpoint.y) diff_count++;
1989 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
1990 technically be correct as it's not precisely defined by docs. */
1991 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
1992 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
1994 if (color & 0xffffff) diff_count2++;
1996 else
1998 DWORD r = (color & 0xff0000) >> 16;
1999 DWORD g = (color & 0xff00) >> 8;
2000 DWORD b = (color & 0xff);
2002 if (r != 0xff || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2003 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2008 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2009 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2011 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2012 MIN(diff_count, diff_count2), i1);
2014 loadpoint.x /= 2;
2015 loadpoint.y /= 2;
2016 loadrect.top /= 2;
2017 loadrect.left /= 2;
2018 loadrect.right = (loadrect.right + 1) / 2;
2019 loadrect.bottom = (loadrect.bottom + 1) / 2;
2022 /* This crashes on native (tested on real windows XP / directx9 / nvidia and
2023 * qemu Win98 / directx7 / RGB software rasterizer):
2024 * passing non toplevel surfaces (sublevels) to Load (DX7 docs tell not to do this)
2025 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][1], NULL, texture_levels[0][1], NULL, 0);
2028 /* Freed in reverse order as native seems to dislike and crash on freeing top level surface first. */
2029 for (i = 0; i < 2; i++)
2031 for (i1 = 7; i1 >= 0; i1--)
2033 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2036 memset(texture_levels, 0, sizeof(texture_levels));
2038 /* Test texture size mismatch. */
2039 for (i = 0; i < 2; i++)
2041 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2042 ddsd.dwSize = sizeof(ddsd);
2043 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2044 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2045 ddsd.dwWidth = i ? 256 : 128;
2046 ddsd.dwHeight = 128;
2047 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2048 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2049 if (FAILED(hr)) goto out;
2052 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2053 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2055 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], NULL, texture_levels[1][0], NULL, 0);
2056 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2058 IDirectDrawSurface7_Release(texture_levels[0][0]);
2059 IDirectDrawSurface7_Release(texture_levels[1][0]);
2060 memset(texture_levels, 0, sizeof(texture_levels));
2062 memset(&d3dcaps, 0, sizeof(d3dcaps));
2063 hr = IDirect3DDevice7_GetCaps(lpD3DDevice, &d3dcaps);
2064 ok(hr == D3D_OK, "IDirect3DDevice7_GetCaps returned %08x\n", hr);
2066 if (!(d3dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2068 skip("No cubemap support\n");
2070 else
2072 /* Test loading mipmapped cubemap texture subrectangle from another similar texture. */
2073 for (i = 0; i < 2; i++)
2075 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2076 ddsd.dwSize = sizeof(ddsd);
2077 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2078 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2079 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2080 ddsd.dwWidth = 128;
2081 ddsd.dwHeight = 128;
2082 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2083 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2084 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2085 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2086 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2087 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2088 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[i][0][0], NULL);
2089 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2090 if (FAILED(hr)) goto out;
2092 flags = DDSCAPS2_CUBEMAP_NEGATIVEX;
2093 for (i1 = 1; i1 < 6; i1++, flags <<= 1)
2095 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2096 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | flags;
2097 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][0][0], &ddsd.ddsCaps, &cube_face_levels[i][i1][0]);
2098 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2099 if (FAILED(hr)) goto out;
2102 for (i1 = 0; i1 < 6; i1++)
2104 /* Check the number of created mipmaps */
2105 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2106 ddsd.dwSize = sizeof(ddsd);
2107 hr = IDirectDrawSurface7_GetSurfaceDesc(cube_face_levels[i][i1][0], &ddsd);
2108 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2109 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2110 if (U2(ddsd).dwMipMapCount != 8) goto out;
2112 for (i2 = 1; i2 < 8; i2++)
2114 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2115 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
2116 hr = IDirectDrawSurface7_GetAttachedSurface(cube_face_levels[i][i1][i2 - 1], &ddsd.ddsCaps, &cube_face_levels[i][i1][i2]);
2117 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2118 if (FAILED(hr)) goto out;
2123 for (i = 0; i < 6; i++)
2124 for (i1 = 0; i1 < 8; i1++)
2126 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2127 ddsd.dwSize = sizeof(ddsd);
2128 hr = IDirectDrawSurface7_Lock(cube_face_levels[0][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2129 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2130 if (FAILED(hr)) goto out;
2132 for (y = 0 ; y < ddsd.dwHeight; y++)
2134 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2136 for (x = 0; x < ddsd.dwWidth; x++)
2138 /* face number in low 4 bits of red, x stored in green component, y in blue. */
2139 DWORD color = 0xf00000 | (i << 16) | (x << 8) | y;
2140 *textureRow++ = color;
2144 hr = IDirectDrawSurface7_Unlock(cube_face_levels[0][i][i1], NULL);
2145 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2148 for (i = 0; i < 6; i++)
2149 for (i1 = 0; i1 < 8; i1++)
2151 memset(&ddbltfx, 0, sizeof(ddbltfx));
2152 ddbltfx.dwSize = sizeof(ddbltfx);
2153 U5(ddbltfx).dwFillColor = 0;
2154 hr = IDirectDrawSurface7_Blt(cube_face_levels[1][i][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2155 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2158 loadpoint.x = loadpoint.y = 10;
2159 loadrect.left = 30;
2160 loadrect.top = 20;
2161 loadrect.right = 93;
2162 loadrect.bottom = 52;
2164 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], &loadpoint, cube_face_levels[0][0][0], &loadrect,
2165 DDSCAPS2_CUBEMAP_ALLFACES);
2166 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2168 for (i = 0; i < 6; i++)
2170 loadpoint.x = loadpoint.y = 10;
2171 loadrect.left = 30;
2172 loadrect.top = 20;
2173 loadrect.right = 93;
2174 loadrect.bottom = 52;
2176 for (i1 = 0; i1 < 8; i1++)
2178 diff_count = 0;
2179 diff_count2 = 0;
2181 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2182 ddsd.dwSize = sizeof(ddsd);
2183 hr = IDirectDrawSurface7_Lock(cube_face_levels[1][i][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2184 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2185 if (FAILED(hr)) goto out;
2187 for (y = 0 ; y < ddsd.dwHeight; y++)
2189 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2191 for (x = 0; x < ddsd.dwWidth; x++)
2193 DWORD color = *textureRow++;
2195 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2196 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2198 if (color & 0xffffff) diff_count++;
2200 else
2202 DWORD r = (color & 0xff0000) >> 16;
2203 DWORD g = (color & 0xff00) >> 8;
2204 DWORD b = (color & 0xff);
2206 if (r != (0xf0 | i) || g != x + loadrect.left - loadpoint.x ||
2207 b != y + loadrect.top - loadpoint.y) diff_count++;
2210 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2211 technically be correct as it's not precisely defined by docs. */
2212 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2213 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2215 if (color & 0xffffff) diff_count2++;
2217 else
2219 DWORD r = (color & 0xff0000) >> 16;
2220 DWORD g = (color & 0xff00) >> 8;
2221 DWORD b = (color & 0xff);
2223 if (r != (0xf0 | i) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2224 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2229 hr = IDirectDrawSurface7_Unlock(cube_face_levels[1][i][i1], NULL);
2230 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2232 ok(diff_count == 0 || diff_count2 == 0,
2233 "Unexpected destination texture level pixels; %u differences at face %x level %d\n",
2234 MIN(diff_count, diff_count2), i, i1);
2236 loadpoint.x /= 2;
2237 loadpoint.y /= 2;
2238 loadrect.top /= 2;
2239 loadrect.left /= 2;
2240 loadrect.right = (loadrect.right + 1) / 2;
2241 loadrect.bottom = (loadrect.bottom + 1) / 2;
2245 for (i = 0; i < 2; i++)
2246 for (i1 = 5; i1 >= 0; i1--)
2247 for (i2 = 7; i2 >= 0; i2--)
2249 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2251 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2253 /* Test cubemap loading from regular texture. */
2254 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2255 ddsd.dwSize = sizeof(ddsd);
2256 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2257 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2258 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
2259 ddsd.dwWidth = 128;
2260 ddsd.dwHeight = 128;
2261 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2262 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2263 if (FAILED(hr)) goto out;
2265 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2266 ddsd.dwSize = sizeof(ddsd);
2267 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2268 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2269 ddsd.dwWidth = 128;
2270 ddsd.dwHeight = 128;
2271 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2272 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2273 if (FAILED(hr)) goto out;
2275 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, texture_levels[0][0], NULL,
2276 DDSCAPS2_CUBEMAP_ALLFACES);
2277 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2279 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2280 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2281 IDirectDrawSurface7_Release(texture_levels[0][0]);
2282 memset(texture_levels, 0, sizeof(texture_levels));
2284 /* Test cubemap loading from cubemap with different number of faces. */
2285 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2286 ddsd.dwSize = sizeof(ddsd);
2287 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2288 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2289 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
2290 ddsd.dwWidth = 128;
2291 ddsd.dwHeight = 128;
2292 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[0][0][0], NULL);
2293 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2294 if (FAILED(hr)) goto out;
2296 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2297 ddsd.dwSize = sizeof(ddsd);
2298 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2299 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
2300 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY;
2301 ddsd.dwWidth = 128;
2302 ddsd.dwHeight = 128;
2303 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &cube_face_levels[1][0][0], NULL);
2304 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2305 if (FAILED(hr)) goto out;
2307 /* INVALIDPARAMS tests currently would fail because wine doesn't support partial cube faces
2308 (the above created cubemaps will have all faces. */
2309 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2310 DDSCAPS2_CUBEMAP_ALLFACES);
2311 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2313 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2314 DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY);
2315 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2317 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[0][0][0], NULL, cube_face_levels[1][0][0], NULL,
2318 DDSCAPS2_CUBEMAP_POSITIVEX);
2319 todo_wine ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2321 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2322 DDSCAPS2_CUBEMAP_ALLFACES);
2323 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2325 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2326 DDSCAPS2_CUBEMAP_POSITIVEX);
2327 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2329 hr = IDirect3DDevice7_Load(lpD3DDevice, cube_face_levels[1][0][0], NULL, cube_face_levels[0][0][0], NULL,
2330 DDSCAPS2_CUBEMAP_POSITIVEZ);
2331 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2333 IDirectDrawSurface7_Release(cube_face_levels[0][0][0]);
2334 IDirectDrawSurface7_Release(cube_face_levels[1][0][0]);
2335 memset(cube_face_levels, 0, sizeof(cube_face_levels));
2338 /* Test texture loading with different mip level count (larger levels match, smaller levels missing in destination. */
2339 for (i = 0; i < 2; i++)
2341 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2342 ddsd.dwSize = sizeof(ddsd);
2343 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
2344 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2345 ddsd.dwWidth = 128;
2346 ddsd.dwHeight = 128;
2347 U2(ddsd).dwMipMapCount = i ? 4 : 8;
2348 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2349 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2350 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2351 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2352 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2353 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2354 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2355 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2356 if (FAILED(hr)) goto out;
2358 /* Check the number of created mipmaps */
2359 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2360 ddsd.dwSize = sizeof(ddsd);
2361 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2362 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2363 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2364 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2366 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2368 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2369 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2370 if (FAILED(hr)) goto out;
2374 for (i1 = 0; i1 < 8; i1++)
2376 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2377 ddsd.dwSize = sizeof(ddsd);
2378 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2379 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2380 if (FAILED(hr)) goto out;
2382 for (y = 0 ; y < ddsd.dwHeight; y++)
2384 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2386 for (x = 0; x < ddsd.dwWidth; x++)
2388 /* x stored in green component, y in blue. */
2389 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2390 *textureRow++ = color;
2394 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2395 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2398 for (i1 = 0; i1 < 4; i1++)
2400 memset(&ddbltfx, 0, sizeof(ddbltfx));
2401 ddbltfx.dwSize = sizeof(ddbltfx);
2402 U5(ddbltfx).dwFillColor = 0;
2403 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2404 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2407 loadpoint.x = loadpoint.y = 31;
2408 loadrect.left = 30;
2409 loadrect.top = 20;
2410 loadrect.right = 93;
2411 loadrect.bottom = 52;
2413 /* Destination mip levels are a subset of source mip levels. */
2414 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2415 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2417 for (i1 = 0; i1 < 4; i1++)
2419 diff_count = 0;
2420 diff_count2 = 0;
2422 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2423 ddsd.dwSize = sizeof(ddsd);
2424 hr = IDirectDrawSurface7_Lock(texture_levels[1][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2425 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2426 if (FAILED(hr)) goto out;
2428 for (y = 0 ; y < ddsd.dwHeight; y++)
2430 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2432 for (x = 0; x < ddsd.dwWidth; x++)
2434 DWORD color = *textureRow++;
2436 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2437 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2439 if (color & 0xffffff) diff_count++;
2441 else
2443 DWORD r = (color & 0xff0000) >> 16;
2444 DWORD g = (color & 0xff00) >> 8;
2445 DWORD b = (color & 0xff);
2447 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2448 b != y + loadrect.top - loadpoint.y) diff_count++;
2451 /* This codepath is for software RGB device. It has what looks like some weird off by one errors, but may
2452 technically be correct as it's not precisely defined by docs. */
2453 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2454 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top + 1)
2456 if (color & 0xffffff) diff_count2++;
2458 else
2460 DWORD r = (color & 0xff0000) >> 16;
2461 DWORD g = (color & 0xff00) >> 8;
2462 DWORD b = (color & 0xff);
2464 if (r != (0xf0 | i1) || !IS_VALUE_NEAR(g, x + loadrect.left - loadpoint.x) ||
2465 !IS_VALUE_NEAR(b, y + loadrect.top - loadpoint.y)) diff_count2++;
2470 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i1], NULL);
2471 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2473 ok(diff_count == 0 || diff_count2 == 0, "Unexpected destination texture level pixels; %u differences at %d level\n",
2474 MIN(diff_count, diff_count2), i1);
2476 loadpoint.x /= 2;
2477 loadpoint.y /= 2;
2478 loadrect.top /= 2;
2479 loadrect.left /= 2;
2480 loadrect.right = (loadrect.right + 1) / 2;
2481 loadrect.bottom = (loadrect.bottom + 1) / 2;
2484 /* Destination mip levels are a superset of source mip levels (should fail). */
2485 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[0][0], &loadpoint, texture_levels[1][0], &loadrect, 0);
2486 ok(hr==DDERR_INVALIDPARAMS, "IDirect3DDevice7_Load returned: %x\n",hr);
2488 for (i = 0; i < 2; i++)
2490 for (i1 = 7; i1 >= 0; i1--)
2492 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2495 memset(texture_levels, 0, sizeof(texture_levels));
2497 /* Test loading from mipmap texture to a regular texture that matches one sublevel in size. */
2498 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2499 ddsd.dwSize = sizeof(ddsd);
2500 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2501 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2502 ddsd.dwWidth = 128;
2503 ddsd.dwHeight = 128;
2504 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2505 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2506 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2507 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2508 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2509 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2510 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[0][0], NULL);
2511 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2512 if (FAILED(hr)) goto out;
2514 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2515 ddsd.dwSize = sizeof(ddsd);
2516 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2517 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2518 ddsd.dwWidth = 32;
2519 ddsd.dwHeight = 32;
2520 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2521 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2522 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2523 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2524 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2525 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2526 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[1][0], NULL);
2527 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2528 if (FAILED(hr)) goto out;
2530 for (i1 = 1; i1 < 8; i1++)
2532 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[0][i1 - 1], &ddsd.ddsCaps, &texture_levels[0][i1]);
2533 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2534 if (FAILED(hr)) goto out;
2537 for (i1 = 0; i1 < 8; i1++)
2539 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2540 ddsd.dwSize = sizeof(ddsd);
2541 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2542 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2543 if (FAILED(hr)) goto out;
2545 for (y = 0 ; y < ddsd.dwHeight; y++)
2547 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2549 for (x = 0; x < ddsd.dwWidth; x++)
2551 /* x stored in green component, y in blue. */
2552 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2553 *textureRow++ = color;
2557 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2558 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2561 memset(&ddbltfx, 0, sizeof(ddbltfx));
2562 ddbltfx.dwSize = sizeof(ddbltfx);
2563 U5(ddbltfx).dwFillColor = 0;
2564 hr = IDirectDrawSurface7_Blt(texture_levels[1][0], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2565 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2567 loadpoint.x = loadpoint.y = 32;
2568 loadrect.left = 32;
2569 loadrect.top = 32;
2570 loadrect.right = 96;
2571 loadrect.bottom = 96;
2573 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2574 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2576 loadpoint.x /= 4;
2577 loadpoint.y /= 4;
2578 loadrect.top /= 4;
2579 loadrect.left /= 4;
2580 loadrect.right = (loadrect.right + 3) / 4;
2581 loadrect.bottom = (loadrect.bottom + 3) / 4;
2583 /* NOTE: something in either nvidia driver or directx9 on WinXP appears to be broken:
2584 * this kind of Load calls (to subset with smaller surface(s)) produces wrong results with
2585 * copied subrectangles divided more than needed, without apparent logic. But it works
2586 * as expected on qemu / Win98 / directx7 / RGB device. Some things are broken on XP, e.g.
2587 * some games don't work that worked in Win98, so it is assumed here XP results are wrong.
2588 * The following code attempts to detect broken results, actual tests will then be skipped
2590 load_mip_subset_broken = TRUE;
2591 diff_count = 0;
2593 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2594 ddsd.dwSize = sizeof(ddsd);
2595 hr = IDirectDrawSurface7_Lock(texture_levels[1][0], NULL, &ddsd, DDLOCK_WAIT, NULL);
2596 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2597 if (FAILED(hr)) goto out;
2599 for (y = 0 ; y < ddsd.dwHeight; y++)
2601 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2603 for (x = 0; x < ddsd.dwWidth; x++)
2605 DWORD color = *textureRow++;
2607 if (x < 2 || x >= 2 + 4 ||
2608 y < 2 || y >= 2 + 4)
2610 if (color & 0xffffff) diff_count++;
2612 else
2614 DWORD r = (color & 0xff0000) >> 16;
2616 if ((r & (0xf0)) != 0xf0) diff_count++;
2621 if (diff_count) load_mip_subset_broken = FALSE;
2623 if (load_mip_subset_broken) {
2624 skip("IDirect3DDevice7_Load is broken (happens on some modern Windows installations like XP). Skipping affected tests.\n");
2625 } else {
2626 diff_count = 0;
2628 for (y = 0 ; y < ddsd.dwHeight; y++)
2630 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2632 for (x = 0; x < ddsd.dwWidth; x++)
2634 DWORD color = *textureRow++;
2636 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2637 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2639 if (color & 0xffffff) diff_count++;
2641 else
2643 DWORD r = (color & 0xff0000) >> 16;
2644 DWORD g = (color & 0xff00) >> 8;
2645 DWORD b = (color & 0xff);
2647 if (r != (0xf0 | 2) || g != x + loadrect.left - loadpoint.x ||
2648 b != y + loadrect.top - loadpoint.y) diff_count++;
2654 hr = IDirectDrawSurface7_Unlock(texture_levels[1][0], NULL);
2655 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2657 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences\n", diff_count);
2659 for (i = 0; i < 2; i++)
2661 for (i1 = 7; i1 >= 0; i1--)
2663 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2666 memset(texture_levels, 0, sizeof(texture_levels));
2668 if (!load_mip_subset_broken)
2670 /* Test loading when destination mip levels are a subset of source mip levels and start from smaller
2671 * surface (than first source mip level)
2673 for (i = 0; i < 2; i++)
2675 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2676 ddsd.dwSize = sizeof(ddsd);
2677 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2678 if (i) ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
2679 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2680 ddsd.dwWidth = i ? 32 : 128;
2681 ddsd.dwHeight = i ? 32 : 128;
2682 if (i) U2(ddsd).dwMipMapCount = 4;
2683 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2684 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
2685 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 32;
2686 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0x00FF0000;
2687 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x0000FF00;
2688 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x000000FF;
2689 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2690 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2691 if (FAILED(hr)) goto out;
2693 /* Check the number of created mipmaps */
2694 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2695 ddsd.dwSize = sizeof(ddsd);
2696 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2697 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2698 ok(U2(ddsd).dwMipMapCount == (i ? 4 : 8), "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2699 if (U2(ddsd).dwMipMapCount != (i ? 4 : 8)) goto out;
2701 for (i1 = 1; i1 < (i ? 4 : 8); i1++)
2703 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2704 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2705 if (FAILED(hr)) goto out;
2709 for (i1 = 0; i1 < 8; i1++)
2711 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2712 ddsd.dwSize = sizeof(ddsd);
2713 hr = IDirectDrawSurface7_Lock(texture_levels[0][i1], NULL, &ddsd, DDLOCK_WAIT, NULL);
2714 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2715 if (FAILED(hr)) goto out;
2717 for (y = 0 ; y < ddsd.dwHeight; y++)
2719 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2721 for (x = 0; x < ddsd.dwWidth; x++)
2723 /* x stored in green component, y in blue. */
2724 DWORD color = 0xf00000 | (i1 << 16) | (x << 8) | y;
2725 *textureRow++ = color;
2729 hr = IDirectDrawSurface7_Unlock(texture_levels[0][i1], NULL);
2730 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2733 for (i1 = 0; i1 < 4; i1++)
2735 memset(&ddbltfx, 0, sizeof(ddbltfx));
2736 ddbltfx.dwSize = sizeof(ddbltfx);
2737 U5(ddbltfx).dwFillColor = 0;
2738 hr = IDirectDrawSurface7_Blt(texture_levels[1][i1], NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
2739 ok(hr == DD_OK, "IDirectDrawSurface7_Blt failed with %08x\n", hr);
2742 loadpoint.x = loadpoint.y = 0;
2743 loadrect.left = 0;
2744 loadrect.top = 0;
2745 loadrect.right = 64;
2746 loadrect.bottom = 64;
2748 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], &loadpoint, texture_levels[0][0], &loadrect, 0);
2749 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2751 i = 0;
2752 for (i1 = 0; i1 < 8 && i < 4; i1++)
2754 DDSURFACEDESC2 ddsd2;
2756 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2757 ddsd.dwSize = sizeof(ddsd);
2758 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[0][i1], &ddsd);
2759 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2761 memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
2762 ddsd2.dwSize = sizeof(ddsd2);
2763 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[1][i], &ddsd2);
2764 ok(SUCCEEDED(hr), "IDirectDrawSurface7_GetSurfaceDesc returned %#x.\n", hr);
2766 if (ddsd.dwWidth == ddsd2.dwWidth && ddsd.dwHeight == ddsd2.dwHeight)
2768 diff_count = 0;
2770 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2771 ddsd.dwSize = sizeof(ddsd);
2772 hr = IDirectDrawSurface7_Lock(texture_levels[1][i], NULL, &ddsd, DDLOCK_WAIT, NULL);
2773 ok(hr==DD_OK, "IDirectDrawSurface7_Lock returned: %x\n",hr);
2774 if (FAILED(hr)) goto out;
2776 for (y = 0 ; y < ddsd.dwHeight; y++)
2778 DWORD *textureRow = (DWORD*)((char*)ddsd.lpSurface + y * U1(ddsd).lPitch);
2780 for (x = 0; x < ddsd.dwWidth; x++)
2782 DWORD color = *textureRow++;
2784 if (x < loadpoint.x || x >= loadpoint.x + loadrect.right - loadrect.left ||
2785 y < loadpoint.y || y >= loadpoint.y + loadrect.bottom - loadrect.top)
2787 if (color & 0xffffff) diff_count++;
2789 else
2791 DWORD r = (color & 0xff0000) >> 16;
2792 DWORD g = (color & 0xff00) >> 8;
2793 DWORD b = (color & 0xff);
2795 if (r != (0xf0 | i1) || g != x + loadrect.left - loadpoint.x ||
2796 b != y + loadrect.top - loadpoint.y) diff_count++;
2801 hr = IDirectDrawSurface7_Unlock(texture_levels[1][i], NULL);
2802 ok(hr==DD_OK, "IDirectDrawSurface7_Unlock returned: %x\n",hr);
2804 ok(diff_count == 0, "Unexpected destination texture level pixels; %u differences at %d level\n", diff_count, i1);
2806 i++;
2809 loadpoint.x /= 2;
2810 loadpoint.y /= 2;
2811 loadrect.top /= 2;
2812 loadrect.left /= 2;
2813 loadrect.right = (loadrect.right + 1) / 2;
2814 loadrect.bottom = (loadrect.bottom + 1) / 2;
2817 for (i = 0; i < 2; i++)
2819 for (i1 = 7; i1 >= 0; i1--)
2821 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2824 memset(texture_levels, 0, sizeof(texture_levels));
2827 /* Test palette copying. */
2828 for (i = 0; i < 2; i++)
2830 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2831 ddsd.dwSize = sizeof(ddsd);
2832 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2833 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
2834 ddsd.dwWidth = 128;
2835 ddsd.dwHeight = 128;
2836 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2837 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2838 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
2839 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &texture_levels[i][0], NULL);
2840 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2841 if (FAILED(hr)) goto out;
2843 /* Check the number of created mipmaps */
2844 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
2845 ddsd.dwSize = sizeof(ddsd);
2846 hr = IDirectDrawSurface7_GetSurfaceDesc(texture_levels[i][0], &ddsd);
2847 ok(hr==DD_OK,"IDirectDrawSurface7_GetSurfaceDesc returned: %x\n",hr);
2848 ok(U2(ddsd).dwMipMapCount == 8, "unexpected mip count %u\n", U2(ddsd).dwMipMapCount);
2849 if (U2(ddsd).dwMipMapCount != 8) goto out;
2851 for (i1 = 1; i1 < 8; i1++)
2853 hr = IDirectDrawSurface7_GetAttachedSurface(texture_levels[i][i1 - 1], &ddsd.ddsCaps, &texture_levels[i][i1]);
2854 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
2855 if (FAILED(hr)) goto out;
2859 memset(table1, 0, sizeof(table1));
2860 for (i = 0; i < 3; i++)
2862 table1[0].peBlue = i + 1;
2863 hr = IDirectDraw7_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, table1, &palettes[i], NULL);
2864 ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
2865 if (FAILED(hr))
2867 skip("IDirectDraw7_CreatePalette failed; skipping further tests\n");
2868 goto out;
2872 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][0], palettes[0]);
2873 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2875 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2876 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2878 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2879 ok(hr==DDERR_NOPALETTEATTACHED, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2881 hr = IDirectDrawSurface7_SetPalette(texture_levels[0][1], palettes[1]);
2882 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2883 hr = IDirectDrawSurface7_SetPalette(texture_levels[1][0], palettes[2]);
2884 ok(hr==DD_OK, "IDirectDrawSurface7_SetPalette returned: %x\n", hr);
2886 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2887 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2889 memset(table1, 0, sizeof(table1));
2890 hr = IDirectDrawSurface7_GetPalette(texture_levels[1][0], &palettes[4]);
2891 ok(hr==DD_OK, "IDirectDrawSurface7_GetPalette returned: %x\n", hr);
2892 if (SUCCEEDED(hr))
2894 hr = IDirectDrawPalette_GetEntries(palettes[4], 0, 0, 256, table1);
2895 ok(hr == DD_OK, "IDirectDrawPalette_GetEntries returned %08x\n", hr);
2896 ok(table1[0].peBlue == 1, "Unexpected palette color after load: %u\n", (unsigned)table1[0].peBlue);
2899 /* Test colorkey copying. */
2900 ddckey.dwColorSpaceLowValue = ddckey.dwColorSpaceHighValue = 64;
2901 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][0], DDCKEY_SRCBLT, &ddckey);
2902 ok(hr==DD_OK, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2903 hr = IDirectDrawSurface7_SetColorKey(texture_levels[0][1], DDCKEY_SRCBLT, &ddckey);
2904 todo_wine ok(hr==DDERR_NOTONMIPMAPSUBLEVEL, "IDirectDrawSurface7_SetColorKey returned: %x\n", hr);
2906 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2907 ok(hr==DDERR_NOCOLORKEY, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2909 hr = IDirect3DDevice7_Load(lpD3DDevice, texture_levels[1][0], NULL, texture_levels[0][0], NULL, 0);
2910 ok(hr==D3D_OK, "IDirect3DDevice7_Load returned: %x\n",hr);
2912 hr = IDirectDrawSurface7_GetColorKey(texture_levels[1][0], DDCKEY_SRCBLT, &ddckey);
2913 ok(hr==DD_OK, "IDirectDrawSurface7_GetColorKey returned: %x\n", hr);
2914 ok(ddckey.dwColorSpaceLowValue == ddckey.dwColorSpaceHighValue && ddckey.dwColorSpaceLowValue == 64,
2915 "Unexpected color key values: %u - %u\n", ddckey.dwColorSpaceLowValue, ddckey.dwColorSpaceHighValue);
2917 out:
2919 for (i = 0; i < 5; i++)
2921 if (palettes[i]) IDirectDrawPalette_Release(palettes[i]);
2924 for (i = 0; i < 2; i++)
2926 for (i1 = 7; i1 >= 0; i1--)
2928 if (texture_levels[i][i1]) IDirectDrawSurface7_Release(texture_levels[i][i1]);
2932 for (i = 0; i < 2; i++)
2933 for (i1 = 5; i1 >= 0; i1--)
2934 for (i2 = 7; i2 >= 0; i2--)
2936 if (cube_face_levels[i][i1][i2]) IDirectDrawSurface7_Release(cube_face_levels[i][i1][i2]);
2940 static void SetMaterialTest(void)
2942 HRESULT rc;
2944 rc =IDirect3DDevice7_SetMaterial(lpD3DDevice, NULL);
2945 ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc);
2948 static void ComputeSphereVisibility(void)
2950 D3DMATRIX proj, view, world;
2951 D3DVALUE radius[3];
2952 D3DVECTOR center[3];
2953 DWORD result[3];
2954 HRESULT rc;
2956 world._11=1.0; world._12=0.0; world._13=0.0; world._14=0.0;
2957 world._21=0.0; world._22=1.0; world._23=0.0; world._24=0.0;
2958 world._31=0.0; world._32=0.0; world._33=1.0; world._34=0.0;
2959 world._41=0.0; world._42=0.0; world._43=0.0; world._44=1.0;
2961 view._11=1.000000; view._12=0.000000; view._13=0.000000; view._14=0.000000;
2962 view._21=0.000000; view._22=0.768221; view._23=-0.640185; view._24=0.000000;
2963 view._31=-0.000000; view._32=0.640185; view._33=0.768221; view._34=0.000000;
2964 view._41=-14.852037; view._42=9.857489; view._43=11.600972; view._44=1.000000;
2966 proj._11=1.810660; proj._12=0.000000; proj._13=0.00000; proj._14=0.000000;
2967 proj._21=0.000000; proj._22=2.414213; proj._23=0.000000, proj._24=0.000000;
2968 proj._31=0.000000; proj._32=0.000000; proj._33=1.020408, proj._34=1.000000;
2969 proj._41=0.000000; proj._42=0.000000; proj._43=-0.102041; proj._44=0.000000;
2971 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_WORLD, &world);
2972 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
2973 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
2975 U1(center[0]).x=11.461533;
2976 U2(center[0]).y=-4.761727;
2977 U3(center[0]).z=-1.171646;
2979 radius[0]=38.252632;
2981 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
2983 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2984 ok(result[0] == 0x3f, "Expected 0x3f, got %x\n", result[0]);
2986 U1(center[0]).x=-3.515620; U2(center[0]).y=-1.560661; U3(center[0]).z=-12.464638;
2987 radius[0]=4.354097;
2988 U1(center[1]).x=14.290396; U2(center[1]).y=-2.981143; U3(center[1]).z=-24.311312;
2989 radius[1]=12.500704;
2990 U1(center[2]).x=1.461626; U2(center[2]).y=-6.093709; U3(center[2]).z=-13.901010;
2991 radius[2]=17.251318;
2993 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 3, 0, result);
2995 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2996 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
2997 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
2998 ok(result[1] == 0x3f, "Expected 0x3f, got %x\n", result[1]);
2999 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3000 ok(result[2] == 0x3f, "Expected 0x3f, got %x\n", result[2]);
3002 view._11=1.0; view._12=0.0; view._13=0.0; view._14=0.0;
3003 view._21=0.0; view._22=1.0; view._23=0.0; view._24=0.0;
3004 view._31=0.0; view._32=0.0; view._33=1.0; view._34=0.0;
3005 view._41=0.0; view._42=0.0; view._43=0.0; view._44=1.0;
3007 proj._11=10.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3008 proj._21=0.0; proj._22=10.0; proj._23=0.0, proj._24=0.0;
3009 proj._31=0.0; proj._32=0.0; proj._33=10.0, proj._34=0.0;
3010 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3012 U1(center[0]).x=0.0;
3013 U2(center[0]).y=0.0;
3014 U3(center[0]).z=0.05;
3016 radius[0]=0.04;
3018 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_VIEW , &view);
3019 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3021 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3023 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3024 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3026 proj._11=1.0; proj._12=0.0; proj._13=0.0; proj._14=0.0;
3027 proj._21=0.0; proj._22=1.0; proj._23=0.0, proj._24=0.0;
3028 proj._31=0.0; proj._32=0.0; proj._33=1.0, proj._34=0.0;
3029 proj._41=0.0; proj._42=0.0; proj._43=0.0; proj._44=1.0;
3031 IDirect3DDevice7_SetTransform(lpD3DDevice, D3DTRANSFORMSTATE_PROJECTION, &proj);
3033 U1(center[0]).x=0.0;
3034 U2(center[0]).y=0.0;
3035 U3(center[0]).z=0.5;
3037 radius[0]=0.5;
3039 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3041 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3042 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3044 U1(center[0]).x=0.0;
3045 U2(center[0]).y=0.0;
3046 U3(center[0]).z=0.0;
3048 radius[0]=0.0;
3050 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3052 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3053 ok(result[0] == 0x0, "Expected 0x0, got %x\n", result[0]);
3055 U1(center[0]).x=-1.0;
3056 U2(center[0]).y=-1.0;
3057 U3(center[0]).z=0.50;
3059 radius[0]=0.25;
3061 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3063 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3064 ok(result[0] == 0x9, "Expected 0x9, got %x\n", result[0]);
3066 U1(center[0]).x=-20.0;
3067 U2(center[0]).y=0.0;
3068 U3(center[0]).z=0.50;
3070 radius[0]=3.0;
3072 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3074 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3075 ok(result[0] == 0x103d, "Expected 0x103d, got %x\n", result[0]);
3077 U1(center[0]).x=20.0;
3078 U2(center[0]).y=0.0;
3079 U3(center[0]).z=0.50;
3081 radius[0]=3.0f;
3083 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3085 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3086 ok(result[0] == 0x203e, "Expected 0x203e, got %x\n", result[0]);
3088 U1(center[0]).x=0.0;
3089 U2(center[0]).y=-20.0;
3090 U3(center[0]).z=0.50;
3092 radius[0]=3.0;
3094 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3096 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3097 ok(result[0] == 0x803b, "Expected 0x803b, got %x\n", result[0]);
3099 U1(center[0]).x=0.0;
3100 U2(center[0]).y=20.0;
3101 U3(center[0]).z=0.5;
3103 radius[0]=3.0;
3105 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3107 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3108 ok(result[0] == 0x4037, "Expected 0x4037, got %x\n", result[0]);
3110 U1(center[0]).x=0.0;
3111 U2(center[0]).y=0.0;
3112 U3(center[0]).z=-20;
3114 radius[0]=3.0;
3116 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3118 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3119 ok(result[0] == 0x1001f, "Expected 0x1001f, got %x\n", result[0]);
3121 U1(center[0]).x=0.0;
3122 U2(center[0]).y=0.0;
3123 U3(center[0]).z=20.0;
3125 radius[0]=3.0;
3127 rc = IDirect3DDevice7_ComputeSphereVisibility(lpD3DDevice, center, radius, 1, 0, result);
3129 ok(rc == D3D_OK, "Expected D3D_OK, received %x\n", rc);
3130 ok(result[0] == 0x2002f, "Expected 0x2002f, got %x\n", result[0]);
3133 static void SetRenderTargetTest(void)
3135 HRESULT hr;
3136 IDirectDrawSurface7 *newrt, *failrt, *oldrt;
3137 D3DVIEWPORT7 vp;
3138 DDSURFACEDESC2 ddsd, ddsd2;
3139 DWORD stateblock;
3141 memset(&ddsd, 0, sizeof(ddsd));
3142 ddsd.dwSize = sizeof(ddsd);
3143 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3144 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
3145 ddsd.dwWidth = 64;
3146 ddsd.dwHeight = 64;
3148 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &newrt, NULL);
3149 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3150 if(FAILED(hr))
3152 skip("Skipping SetRenderTarget test\n");
3153 return;
3156 memset(&ddsd2, 0, sizeof(ddsd2));
3157 ddsd2.dwSize = sizeof(ddsd2);
3158 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3159 ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ZBUFFER;
3160 ddsd2.dwWidth = 64;
3161 ddsd2.dwHeight = 64;
3162 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
3163 U4(ddsd2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3164 U1(U4(ddsd2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3165 U3(U4(ddsd2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3167 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd2, &failrt, NULL);
3168 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed, hr=0x%08x\n", hr);
3170 memset(&vp, 0, sizeof(vp));
3171 vp.dwX = 10;
3172 vp.dwY = 10;
3173 vp.dwWidth = 246;
3174 vp.dwHeight = 246;
3175 vp.dvMinZ = 0.25;
3176 vp.dvMaxZ = 0.75;
3177 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3178 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3180 hr = IDirect3DDevice7_GetRenderTarget(lpD3DDevice, &oldrt);
3181 ok(hr == DD_OK, "IDirect3DDevice7_GetRenderTarget failed, hr=0x%08x\n", hr);
3183 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, failrt, 0);
3184 ok(hr != D3D_OK, "IDirect3DDevice7_SetRenderTarget succeeded\n");
3186 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, newrt, 0);
3187 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3188 memset(&vp, 0xff, sizeof(vp));
3189 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3190 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3191 ok(vp.dwX == 10, "vp.dwX is %u, expected 10\n", vp.dwX);
3192 ok(vp.dwY == 10, "vp.dwY is %u, expected 10\n", vp.dwY);
3193 ok(vp.dwWidth == 246, "vp.dwWidth is %u, expected 246\n", vp.dwWidth);
3194 ok(vp.dwHeight == 246, "vp.dwHeight is %u, expected 246\n", vp.dwHeight);
3195 ok(vp.dvMinZ == 0.25, "vp.dvMinZ is %f, expected 0.25\n", vp.dvMinZ);
3196 ok(vp.dvMaxZ == 0.75, "vp.dvMaxZ is %f, expected 0.75\n", vp.dvMaxZ);
3198 memset(&vp, 0, sizeof(vp));
3199 vp.dwX = 0;
3200 vp.dwY = 0;
3201 vp.dwWidth = 64;
3202 vp.dwHeight = 64;
3203 vp.dvMinZ = 0.0;
3204 vp.dvMaxZ = 1.0;
3205 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3206 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3208 hr = IDirect3DDevice7_BeginStateBlock(lpD3DDevice);
3209 ok(hr == D3D_OK, "IDirect3DDevice7_BeginStateblock failed, hr=0x%08x\n", hr);
3210 hr = IDirect3DDevice7_SetRenderTarget(lpD3DDevice, oldrt, 0);
3211 ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderTarget failed, hr=0x%08x\n", hr);
3213 /* Check this twice, before and after ending the stateblock */
3214 memset(&vp, 0xff, sizeof(vp));
3215 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3216 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3217 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3218 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3219 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3220 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3221 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3222 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3224 hr = IDirect3DDevice7_EndStateBlock(lpD3DDevice, &stateblock);
3225 ok(hr == D3D_OK, "IDirect3DDevice7_EndStateblock failed, hr=0x%08x\n", hr);
3227 memset(&vp, 0xff, sizeof(vp));
3228 hr = IDirect3DDevice7_GetViewport(lpD3DDevice, &vp);
3229 ok(hr == D3D_OK, "IDirect3DDevice7_GetViewport failed, hr=0x%08x\n", hr);
3230 ok(vp.dwX == 0, "vp.dwX is %u, expected 0\n", vp.dwX);
3231 ok(vp.dwY == 0, "vp.dwY is %u, expected 0\n", vp.dwY);
3232 ok(vp.dwWidth == 64, "vp.dwWidth is %u, expected 64\n", vp.dwWidth);
3233 ok(vp.dwHeight == 64, "vp.dwHeight is %u, expected 64\n", vp.dwHeight);
3234 ok(vp.dvMinZ == 0.0, "vp.dvMinZ is %f, expected 0.0\n", vp.dvMinZ);
3235 ok(vp.dvMaxZ == 1.0, "vp.dvMaxZ is %f, expected 1.0\n", vp.dvMaxZ);
3237 hr = IDirect3DDevice7_DeleteStateBlock(lpD3DDevice, stateblock);
3238 ok(hr == D3D_OK, "IDirect3DDevice7_DeleteStateblock failed, hr=0x%08x\n", hr);
3240 memset(&vp, 0, sizeof(vp));
3241 vp.dwX = 0;
3242 vp.dwY = 0;
3243 vp.dwWidth = 256;
3244 vp.dwHeight = 256;
3245 vp.dvMinZ = 0.0;
3246 vp.dvMaxZ = 0.0;
3247 hr = IDirect3DDevice7_SetViewport(lpD3DDevice, &vp);
3248 ok(hr == D3D_OK, "IDirect3DDevice7_SetViewport failed, hr=0x%08x\n", hr);
3250 IDirectDrawSurface7_Release(oldrt);
3251 IDirectDrawSurface7_Release(newrt);
3252 IDirectDrawSurface7_Release(failrt);
3255 static const UINT *expect_messages;
3257 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
3259 if (expect_messages && message == *expect_messages) ++expect_messages;
3261 return DefWindowProcA(hwnd, message, wparam, lparam);
3264 static void test_wndproc(void)
3266 IDirectDraw7 *ddraw7;
3267 WNDCLASSA wc = {0};
3268 LONG_PTR proc;
3269 HWND window;
3270 HRESULT hr;
3271 ULONG ref;
3273 static const UINT messages[] =
3275 WM_WINDOWPOSCHANGING,
3276 WM_ACTIVATE,
3277 WM_SETFOCUS,
3281 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3282 if (FAILED(hr))
3284 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3285 return;
3288 wc.lpfnWndProc = test_proc;
3289 wc.lpszClassName = "d3d7_test_wndproc_wc";
3290 ok(RegisterClassA(&wc), "Failed to register window class.\n");
3292 window = CreateWindowA("d3d7_test_wndproc_wc", "d3d7_test",
3293 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
3295 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3296 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3297 (LONG_PTR)test_proc, proc);
3299 expect_messages = messages;
3301 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3302 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3303 if (FAILED(hr))
3305 IDirectDraw7_Release(ddraw7);
3306 goto done;
3309 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
3310 expect_messages = NULL;
3312 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3313 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3314 (LONG_PTR)test_proc, proc);
3316 ref = IDirectDraw7_Release(ddraw7);
3317 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3319 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3320 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3321 (LONG_PTR)test_proc, proc);
3323 hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
3324 if (FAILED(hr))
3326 skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
3327 return;
3330 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3331 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
3332 (LONG_PTR)test_proc, proc);
3334 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3335 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
3336 if (FAILED(hr))
3338 IDirectDraw7_Release(ddraw7);
3339 goto done;
3342 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
3343 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
3344 (LONG_PTR)test_proc, proc);
3346 ref = IDirectDraw7_Release(ddraw7);
3347 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
3349 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
3350 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
3351 (LONG_PTR)DefWindowProcA, proc);
3353 done:
3354 expect_messages = NULL;
3355 DestroyWindow(window);
3356 UnregisterClassA("d3d7_test_wndproc_wc", GetModuleHandleA(NULL));
3359 static void VertexBufferLockRest(void)
3361 D3DVERTEXBUFFERDESC desc;
3362 IDirect3DVertexBuffer7 *buffer;
3363 HRESULT hr;
3364 unsigned int i;
3365 void *data;
3366 const struct
3368 DWORD flags;
3369 const char *debug_string;
3370 HRESULT result;
3372 test_data[] =
3374 {0, "(none)", D3D_OK },
3375 {DDLOCK_WAIT, "DDLOCK_WAIT", D3D_OK },
3376 {DDLOCK_EVENT, "DDLOCK_EVENT", D3D_OK },
3377 {DDLOCK_READONLY, "DDLOCK_READONLY", D3D_OK },
3378 {DDLOCK_WRITEONLY, "DDLOCK_WRITEONLY", D3D_OK },
3379 {DDLOCK_NOSYSLOCK, "DDLOCK_NOSYSLOCK", D3D_OK },
3380 {DDLOCK_NOOVERWRITE, "DDLOCK_NOOVERWRITE", D3D_OK },
3381 {DDLOCK_DISCARDCONTENTS, "DDLOCK_DISCARDCONTENTS", D3D_OK },
3383 {DDLOCK_READONLY | DDLOCK_WRITEONLY, "DDLOCK_READONLY | DDLOCK_WRITEONLY", D3D_OK },
3384 {DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS, "DDLOCK_READONLY | DDLOCK_DISCARDCONTENTS", D3D_OK },
3385 {0xdeadbeef, "0xdeadbeef", D3D_OK },
3388 memset(&desc, 0 , sizeof(desc));
3389 desc.dwSize = sizeof(desc);
3390 desc.dwCaps = 0;
3391 desc.dwFVF = D3DFVF_XYZ;
3392 desc.dwNumVertices = 64;
3393 hr = IDirect3D7_CreateVertexBuffer(lpD3D, &desc, &buffer, 0);
3394 ok(hr == D3D_OK, "IDirect3D7_CreateVertexBuffer failed, 0x%08x\n", hr);
3396 for(i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3398 hr = IDirect3DVertexBuffer7_Lock(buffer, test_data[i].flags, &data, NULL);
3399 ok(hr == test_data[i].result, "Lock flags %s returned 0x%08x, expected 0x%08x\n",
3400 test_data[i].debug_string, hr, test_data[i].result);
3401 if(SUCCEEDED(hr))
3403 ok(data != NULL, "The data pointer returned by Lock is NULL\n");
3404 hr = IDirect3DVertexBuffer7_Unlock(buffer);
3405 ok(hr == D3D_OK, "IDirect3DVertexBuffer7_Unlock failed, 0x%08x\n", hr);
3409 IDirect3DVertexBuffer7_Release(buffer);
3412 static void FindDevice(void)
3414 static const struct
3416 const GUID *guid;
3417 int todo;
3418 } deviceGUIDs[] =
3420 {&IID_IDirect3DRampDevice, 1},
3421 {&IID_IDirect3DRGBDevice},
3424 static const GUID *nonexistent_deviceGUIDs[] = {&IID_IDirect3DMMXDevice,
3425 &IID_IDirect3DRefDevice,
3426 &IID_IDirect3DTnLHalDevice,
3427 &IID_IDirect3DNullDevice};
3429 D3DFINDDEVICESEARCH search = {0};
3430 D3DFINDDEVICERESULT result = {0};
3431 IDirect3DDevice *d3dhal;
3432 HRESULT hr;
3433 int i;
3435 /* Test invalid parameters. */
3436 hr = IDirect3D_FindDevice(Direct3D1, NULL, NULL);
3437 ok(hr == DDERR_INVALIDPARAMS,
3438 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3440 hr = IDirect3D_FindDevice(Direct3D1, NULL, &result);
3441 ok(hr == DDERR_INVALIDPARAMS,
3442 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3444 hr = IDirect3D_FindDevice(Direct3D1, &search, NULL);
3445 ok(hr == DDERR_INVALIDPARAMS,
3446 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3448 search.dwSize = 0;
3449 result.dwSize = 0;
3451 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3452 ok(hr == DDERR_INVALIDPARAMS,
3453 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3455 search.dwSize = sizeof(search) + 1;
3456 result.dwSize = sizeof(result) + 1;
3458 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3459 ok(hr == DDERR_INVALIDPARAMS,
3460 "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
3462 /* Specifying no flags is permitted. */
3463 search.dwSize = sizeof(search);
3464 search.dwFlags = 0;
3465 result.dwSize = sizeof(result);
3467 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3468 ok(hr == D3D_OK,
3469 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3471 /* Try an arbitrary non-device GUID. */
3472 search.dwSize = sizeof(search);
3473 search.dwFlags = D3DFDS_GUID;
3474 search.guid = IID_IDirect3D;
3475 result.dwSize = sizeof(result);
3477 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3478 ok(hr == DDERR_NOTFOUND,
3479 "Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", hr);
3481 /* These GUIDs appear to be never present. */
3482 for (i = 0; i < sizeof(nonexistent_deviceGUIDs)/sizeof(nonexistent_deviceGUIDs[0]); i++)
3484 search.dwSize = sizeof(search);
3485 search.dwFlags = D3DFDS_GUID;
3486 search.guid = *nonexistent_deviceGUIDs[i];
3487 result.dwSize = sizeof(result);
3489 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3490 ok(hr == DDERR_NOTFOUND,
3491 "[%d] Expected IDirect3D1::FindDevice to return DDERR_NOTFOUND, got 0x%08x\n", i, hr);
3494 /* The HAL device can only be enumerated if hardware acceleration is present. */
3495 search.dwSize = sizeof(search);
3496 search.dwFlags = D3DFDS_GUID;
3497 search.guid = IID_IDirect3DHALDevice;
3498 result.dwSize = sizeof(result);
3500 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3501 trace("IDirect3D::FindDevice returned 0x%08x for the HAL device GUID\n", hr);
3502 if (SUCCEEDED(hr))
3504 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3505 /* Currently Wine only supports the creation of one Direct3D device
3506 * for a given DirectDraw instance. */
3507 todo_wine
3508 ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3510 if (SUCCEEDED(hr))
3511 IDirect3DDevice_Release(d3dhal);
3513 else
3515 hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3516 ok(FAILED(hr), "Expected IDirectDrawSurface::QueryInterface to fail, got 0x%08x\n", hr);
3518 if (SUCCEEDED(hr))
3519 IDirect3DDevice_Release(d3dhal);
3522 /* These GUIDs appear to be always present. */
3523 for (i = 0; i < sizeof(deviceGUIDs)/sizeof(deviceGUIDs[0]); i++)
3525 search.dwSize = sizeof(search);
3526 search.dwFlags = D3DFDS_GUID;
3527 search.guid = *deviceGUIDs[i].guid;
3528 result.dwSize = sizeof(result);
3530 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3532 if (deviceGUIDs[i].todo)
3534 todo_wine
3535 ok(hr == D3D_OK,
3536 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3538 else
3540 ok(hr == D3D_OK,
3541 "[%d] Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", i, hr);
3545 /* Curiously the color model criteria seem to be ignored. */
3546 search.dwSize = sizeof(search);
3547 search.dwFlags = D3DFDS_COLORMODEL;
3548 search.dcmColorModel = 0xdeadbeef;
3549 result.dwSize = sizeof(result);
3551 hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
3552 todo_wine
3553 ok(hr == D3D_OK,
3554 "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
3557 static void BackBuffer3DCreateSurfaceTest(void)
3559 DDSURFACEDESC ddsd;
3560 DDSURFACEDESC created_ddsd;
3561 DDSURFACEDESC2 ddsd2;
3562 IDirectDrawSurface *surf;
3563 IDirectDrawSurface4 *surf4;
3564 IDirectDrawSurface7 *surf7;
3565 HRESULT hr;
3566 IDirectDraw2 *dd2;
3567 IDirectDraw4 *dd4;
3568 IDirectDraw7 *dd7;
3569 DDCAPS ddcaps;
3570 IDirect3DDevice *d3dhal;
3572 const DWORD caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3573 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3575 memset(&ddcaps, 0, sizeof(ddcaps));
3576 ddcaps.dwSize = sizeof(DDCAPS);
3577 hr = IDirectDraw_GetCaps(DirectDraw1, &ddcaps, NULL);
3578 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3580 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3581 return ;
3584 memset(&ddsd, 0, sizeof(ddsd));
3585 ddsd.dwSize = sizeof(ddsd);
3586 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3587 ddsd.dwWidth = 64;
3588 ddsd.dwHeight = 64;
3589 ddsd.ddsCaps.dwCaps = caps;
3590 memset(&ddsd2, 0, sizeof(ddsd2));
3591 ddsd2.dwSize = sizeof(ddsd2);
3592 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3593 ddsd2.dwWidth = 64;
3594 ddsd2.dwHeight = 64;
3595 ddsd2.ddsCaps.dwCaps = caps;
3596 memset(&created_ddsd, 0, sizeof(created_ddsd));
3597 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3599 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
3600 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3601 if (surf != NULL)
3603 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3604 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3605 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3606 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3607 expected_caps);
3609 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
3610 /* Currently Wine only supports the creation of one Direct3D device
3611 for a given DirectDraw instance. It has been created already
3612 in D3D1_createObjects() - IID_IDirect3DRGBDevice */
3613 todo_wine ok(SUCCEEDED(hr), "Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
3615 if (SUCCEEDED(hr))
3616 IDirect3DDevice_Release(d3dhal);
3618 IDirectDrawSurface_Release(surf);
3621 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw2, (void **) &dd2);
3622 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3624 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3625 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3626 DDERR_INVALIDCAPS, hr);
3628 IDirectDraw2_Release(dd2);
3630 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw4, (void **) &dd4);
3631 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3633 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3634 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3635 DDERR_INVALIDCAPS, hr);
3637 IDirectDraw4_Release(dd4);
3639 hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirectDraw7, (void **) &dd7);
3640 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3642 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3643 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3644 DDERR_INVALIDCAPS, hr);
3646 IDirectDraw7_Release(dd7);
3649 static void BackBuffer3DAttachmentTest(void)
3651 HRESULT hr;
3652 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3653 DDSURFACEDESC ddsd;
3654 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3656 hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3657 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3659 /* Perform attachment tests on a back-buffer */
3660 memset(&ddsd, 0, sizeof(ddsd));
3661 ddsd.dwSize = sizeof(ddsd);
3662 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3663 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3664 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3665 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3666 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface2, NULL);
3667 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3669 if (surface2 != NULL)
3671 /* Try a single primary and a two back buffers */
3672 memset(&ddsd, 0, sizeof(ddsd));
3673 ddsd.dwSize = sizeof(ddsd);
3674 ddsd.dwFlags = DDSD_CAPS;
3675 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3676 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface1, NULL);
3677 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3679 memset(&ddsd, 0, sizeof(ddsd));
3680 ddsd.dwSize = sizeof(ddsd);
3681 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3682 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3683 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3684 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3685 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface3, NULL);
3686 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3688 /* This one has a different size */
3689 memset(&ddsd, 0, sizeof(ddsd));
3690 ddsd.dwSize = sizeof(ddsd);
3691 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3692 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_3DDEVICE;
3693 ddsd.dwWidth = 128;
3694 ddsd.dwHeight = 128;
3695 hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surface4, NULL);
3696 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3698 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3699 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3700 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3701 if(SUCCEEDED(hr))
3703 /* Try the reverse without detaching first */
3704 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3705 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3706 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3707 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3709 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3710 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3711 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3712 if(SUCCEEDED(hr))
3714 /* Try to detach reversed */
3715 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3716 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3717 /* Now the proper detach */
3718 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3719 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3721 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3722 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3723 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3724 if(SUCCEEDED(hr))
3726 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3727 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3729 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3730 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3731 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3732 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3734 IDirectDrawSurface_Release(surface4);
3735 IDirectDrawSurface_Release(surface3);
3736 IDirectDrawSurface_Release(surface2);
3737 IDirectDrawSurface_Release(surface1);
3740 hr =IDirectDraw_SetCooperativeLevel(DirectDraw1, NULL, DDSCL_NORMAL);
3741 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3743 DestroyWindow(window);
3746 START_TEST(d3d)
3748 init_function_pointers();
3749 if(!pDirectDrawCreateEx) {
3750 win_skip("function DirectDrawCreateEx not available\n");
3751 return;
3754 if(!CreateDirect3D()) {
3755 skip("Skipping d3d7 tests\n");
3756 } else {
3757 LightTest();
3758 ProcessVerticesTest();
3759 StateTest();
3760 SceneTest();
3761 LimitTest();
3762 D3D7EnumTest();
3763 SetMaterialTest();
3764 ComputeSphereVisibility();
3765 CapsTest();
3766 VertexBufferDescTest();
3767 D3D7_OldRenderStateTest();
3768 DeviceLoadTest();
3769 SetRenderTargetTest();
3770 VertexBufferLockRest();
3771 ReleaseDirect3D();
3774 if (!D3D1_createObjects()) {
3775 skip("Skipping d3d1 tests\n");
3776 } else {
3777 Direct3D1Test();
3778 TextureLoadTest();
3779 ViewportTest();
3780 FindDevice();
3781 BackBuffer3DCreateSurfaceTest();
3782 BackBuffer3DAttachmentTest();
3783 D3D1_releaseObjects();
3786 test_wndproc();