2 * Unit tests for (a few) ddraw surface functions
4 * Copyright (C) 2005 Antoine Chavasse (a.chavasse@gmail.com)
5 * Copyright (C) 2005 Christian Costa
6 * Copyright 2005 Ivan Leo Puoti
7 * Copyright (C) 2007 Stefan Dösinger
8 * Copyright (C) 2008 Alexander Dorofeyev
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/test.h"
32 static LPDIRECTDRAW lpDD = NULL;
35 static BOOL CreateDirectDraw(void)
39 rc = DirectDrawCreate(NULL, &lpDD, NULL);
40 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
42 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
46 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
47 ok(rc==DD_OK,"SetCooperativeLevel returned: %x\n",rc);
53 static void ReleaseDirectDraw(void)
57 IDirectDraw_Release(lpDD);
62 static void MipMapCreationTest(void)
64 LPDIRECTDRAWSURFACE lpDDSMipMapTest;
68 /* First mipmap creation test: create a surface with DDSCAPS_COMPLEX,
69 DDSCAPS_MIPMAP, and DDSD_MIPMAPCOUNT. This create the number of
70 requested mipmap levels. */
71 ddsd.dwSize = sizeof(ddsd);
72 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
73 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
74 U2(ddsd).dwMipMapCount = 3;
77 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
78 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
80 skip("failed to create surface\n");
84 /* Check the number of created mipmaps */
85 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
86 ddsd.dwSize = sizeof(ddsd);
87 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
88 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
89 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
90 "GetSurfaceDesc returned no mipmapcount.\n");
91 ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %d.\n",
92 U2(ddsd).dwMipMapCount);
94 /* Destroy the surface. */
95 IDirectDrawSurface_Release(lpDDSMipMapTest);
98 /* Second mipmap creation test: create a surface without a mipmap
99 count, with DDSCAPS_MIPMAP and without DDSCAPS_COMPLEX.
100 This creates a single mipmap level. */
101 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
102 ddsd.dwSize = sizeof(ddsd);
103 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
104 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
107 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
108 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
110 skip("failed to create surface\n");
113 /* Check the number of created mipmaps */
114 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
115 ddsd.dwSize = sizeof(ddsd);
116 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
117 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
118 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
119 "GetSurfaceDesc returned no mipmapcount.\n");
120 ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %d.\n",
121 U2(ddsd).dwMipMapCount);
123 /* Destroy the surface. */
124 IDirectDrawSurface_Release(lpDDSMipMapTest);
127 /* Third mipmap creation test: create a surface with DDSCAPS_MIPMAP,
128 DDSCAPS_COMPLEX and without DDSD_MIPMAPCOUNT.
129 It's an undocumented features where a chain of mipmaps, starting from
130 he specified size and down to the smallest size, is automatically
132 Anarchy Online needs this feature to work. */
133 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
134 ddsd.dwSize = sizeof(ddsd);
135 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
136 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
139 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
140 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
142 skip("failed to create surface\n");
146 /* Check the number of created mipmaps */
147 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
148 ddsd.dwSize = sizeof(ddsd);
149 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
150 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
151 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
152 "GetSurfaceDesc returned no mipmapcount.\n");
153 ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
154 U2(ddsd).dwMipMapCount);
156 /* Destroy the surface. */
157 IDirectDrawSurface_Release(lpDDSMipMapTest);
160 /* Fourth mipmap creation test: same as above with a different texture
162 The purpose is to verify that the number of generated mipmaps is
163 dependent on the smallest dimension. */
164 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
165 ddsd.dwSize = sizeof(ddsd);
166 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
167 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
170 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
171 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
173 skip("failed to create surface\n");
177 /* Check the number of created mipmaps */
178 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
179 ddsd.dwSize = sizeof(ddsd);
180 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
181 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
182 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
183 "GetSurfaceDesc returned no mipmapcount.\n");
184 ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
185 U2(ddsd).dwMipMapCount);
187 /* Destroy the surface. */
188 IDirectDrawSurface_Release(lpDDSMipMapTest);
191 /* Fifth mipmap creation test: try to create a surface with
192 DDSCAPS_COMPLEX, DDSCAPS_MIPMAP, DDSD_MIPMAPCOUNT,
193 where dwMipMapCount = 0. This should fail. */
195 ddsd.dwSize = sizeof(ddsd);
196 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
197 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
198 U2(ddsd).dwMipMapCount = 0;
201 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
202 ok(rc==DDERR_INVALIDPARAMS,"CreateSurface returned: %x\n",rc);
204 /* Destroy the surface. */
206 IDirectDrawSurface_Release(lpDDSMipMapTest);
210 static void SrcColorKey32BlitTest(void)
212 LPDIRECTDRAWSURFACE lpSrc;
213 LPDIRECTDRAWSURFACE lpDst;
214 DDSURFACEDESC ddsd, ddsd2, ddsd3;
215 DDCOLORKEY DDColorKey;
220 ddsd2.dwSize = sizeof(ddsd2);
221 ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
223 ddsd.dwSize = sizeof(ddsd);
224 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
225 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
226 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
229 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
230 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
231 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
232 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
233 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
234 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
235 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
237 skip("failed to create surface\n");
241 ddsd.dwFlags |= DDSD_CKSRCBLT;
242 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
243 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
244 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
245 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
247 skip("failed to create surface\n");
251 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
252 ok(rc==DD_OK,"Lock returned: %x\n",rc);
253 lpData = ddsd2.lpSurface;
254 lpData[0] = 0xCCCCCCCC;
255 lpData[1] = 0xCCCCCCCC;
256 lpData[2] = 0xCCCCCCCC;
257 lpData[3] = 0xCCCCCCCC;
259 memset(&ddsd3, 0, sizeof(ddsd3));
260 ddsd3.dwSize = sizeof(ddsd3);
261 ddsd3.ddpfPixelFormat.dwSize = sizeof(ddsd3.ddpfPixelFormat);
262 rc = IDirectDrawSurface_GetSurfaceDesc(lpDst, &ddsd3);
263 ok(rc == DD_OK, "IDirectDrawSurface_GetSurfaceDesc between a lock/unlock pair returned %08x\n", rc);
264 ok(ddsd3.lpSurface == ddsd3.lpSurface, "lpSurface from GetSurfaceDesc(%p) differs from the one returned by Lock(%p)\n", ddsd3.lpSurface, ddsd2.lpSurface);
266 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
267 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
269 memset(&ddsd3, 0, sizeof(ddsd3));
270 ddsd3.dwSize = sizeof(ddsd3);
271 ddsd3.ddpfPixelFormat.dwSize = sizeof(ddsd3.ddpfPixelFormat);
272 rc = IDirectDrawSurface_GetSurfaceDesc(lpDst, &ddsd3);
273 ok(rc == DD_OK, "IDirectDrawSurface_GetSurfaceDesc between a lock/unlock pair returned %08x\n", rc);
274 ok(ddsd3.lpSurface == NULL, "lpSurface from GetSurfaceDesc(%p) is not NULL after unlock\n", ddsd3.lpSurface);
276 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
277 ok(rc==DD_OK,"Lock returned: %x\n",rc);
278 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
279 lpData = ddsd2.lpSurface;
280 lpData[0] = 0x77010203;
281 lpData[1] = 0x00010203;
282 lpData[2] = 0x77FF00FF;
283 lpData[3] = 0x00FF00FF;
284 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
285 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
287 IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
289 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
290 ok(rc==DD_OK,"Lock returned: %x\n",rc);
291 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
292 lpData = ddsd2.lpSurface;
293 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
294 * color keying, but copy it to the destination surface. Others apply it for color keying, but
295 * do not copy it into the destination surface.
297 if(lpData[0]==0x00010203) {
298 trace("X channel was not copied into the destination surface\n");
299 ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
300 "Destination data after blitting is not correct\n");
302 ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
303 "Destination data after blitting is not correct\n");
305 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
306 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
308 /* Below we repeat the same test as above but now using BltFast instead of Blt. Before
309 * we can carry out the test we need to restore the color of the destination surface.
311 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
312 ok(rc==DD_OK,"Lock returned: %x\n",rc);
313 lpData = ddsd2.lpSurface;
314 lpData[0] = 0xCCCCCCCC;
315 lpData[1] = 0xCCCCCCCC;
316 lpData[2] = 0xCCCCCCCC;
317 lpData[3] = 0xCCCCCCCC;
318 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
319 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
321 IDirectDrawSurface_BltFast(lpDst, 0, 0, lpSrc, NULL, DDBLTFAST_SRCCOLORKEY);
323 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
324 ok(rc==DD_OK,"Lock returned: %x\n",rc);
325 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
326 lpData = ddsd2.lpSurface;
327 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
328 * color keying, but copy it to the destination surface. Others apply it for color keying, but
329 * do not copy it into the destination surface.
331 if(lpData[0]==0x00010203) {
332 trace("X channel was not copied into the destination surface\n");
333 ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
334 "Destination data after blitting is not correct\n");
336 ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
337 "Destination data after blitting is not correct\n");
339 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
340 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
342 /* Also test SetColorKey */
343 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
344 ok(DDColorKey.dwColorSpaceLowValue == 0xFF00FF && DDColorKey.dwColorSpaceHighValue == 0xFF00FF,
345 "GetColorKey does not return the colorkey used at surface creation\n");
347 DDColorKey.dwColorSpaceLowValue = 0x00FF00;
348 DDColorKey.dwColorSpaceHighValue = 0x00FF00;
349 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
351 DDColorKey.dwColorSpaceLowValue = 0;
352 DDColorKey.dwColorSpaceHighValue = 0;
353 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
354 ok(DDColorKey.dwColorSpaceLowValue == 0x00FF00 && DDColorKey.dwColorSpaceHighValue == 0x00FF00,
355 "GetColorKey does not return the colorkey set with SetColorKey\n");
357 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
358 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
359 IDirectDrawSurface_GetSurfaceDesc(lpSrc, &ddsd);
360 ok(ddsd.ddckCKSrcBlt.dwColorSpaceLowValue == 0x00FF00 && ddsd.ddckCKSrcBlt.dwColorSpaceHighValue == 0x00FF00,
361 "GetSurfaceDesc does not return the colorkey set with SetColorKey\n");
363 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
364 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
365 DDColorKey.dwColorSpaceHighValue = 0x000000;
366 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
368 DDColorKey.dwColorSpaceLowValue = 0;
369 DDColorKey.dwColorSpaceHighValue = 0;
370 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
371 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
372 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
374 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
375 DDColorKey.dwColorSpaceHighValue = 0x000001;
376 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
378 DDColorKey.dwColorSpaceLowValue = 0;
379 DDColorKey.dwColorSpaceHighValue = 0;
380 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
381 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
382 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
384 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
385 DDColorKey.dwColorSpaceHighValue = 0x0000FE;
386 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
388 DDColorKey.dwColorSpaceLowValue = 0;
389 DDColorKey.dwColorSpaceHighValue = 0;
390 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
391 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
392 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
394 IDirectDrawSurface_Release(lpSrc);
395 IDirectDrawSurface_Release(lpDst);
397 /* start with a new set of surfaces to test the color keying parameters to blit */
398 memset(&ddsd, 0, sizeof(ddsd));
399 ddsd.dwSize = sizeof(ddsd);
400 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
401 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
402 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
405 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
406 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
407 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
408 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
409 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
410 ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0xFF0000;
411 ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0xFF0000;
412 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x00FF00;
413 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x00FF00;
414 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
415 ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
418 skip("Failed to create surface\n");
422 /* start with a new set of surfaces to test the color keying parameters to blit */
423 memset(&ddsd, 0, sizeof(ddsd));
424 ddsd.dwSize = sizeof(ddsd);
425 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
426 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
427 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
430 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
431 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
432 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
433 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
434 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
435 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x0000FF;
436 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x0000FF;
437 ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0x000000;
438 ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0x000000;
439 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
440 ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
443 skip("Failed to create surface\n");
444 IDirectDrawSurface_Release(lpDst);
448 memset(&fx, 0, sizeof(fx));
449 fx.dwSize = sizeof(fx);
450 fx.ddckSrcColorkey.dwColorSpaceHighValue = 0x110000;
451 fx.ddckSrcColorkey.dwColorSpaceLowValue = 0x110000;
452 fx.ddckDestColorkey.dwColorSpaceHighValue = 0x001100;
453 fx.ddckDestColorkey.dwColorSpaceLowValue = 0x001100;
455 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
456 ok(rc==DD_OK,"Lock returned: %x\n",rc);
457 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
458 lpData = ddsd2.lpSurface;
459 lpData[0] = 0x000000FF; /* Applies to src blt key in src surface */
460 lpData[1] = 0x00000000; /* Applies to dst blt key in src surface */
461 lpData[2] = 0x00FF0000; /* Dst color key in dst surface */
462 lpData[3] = 0x0000FF00; /* Src color key in dst surface */
463 lpData[4] = 0x00001100; /* Src color key in ddbltfx */
464 lpData[5] = 0x00110000; /* Dst color key in ddbltfx */
465 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
466 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
468 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
469 ok(rc==DD_OK,"Lock returned: %x\n",rc);
470 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
471 lpData = ddsd2.lpSurface;
472 lpData[0] = 0x55555555;
473 lpData[1] = 0x55555555;
474 lpData[2] = 0x55555555;
475 lpData[3] = 0x55555555;
476 lpData[4] = 0x55555555;
477 lpData[5] = 0x55555555;
478 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
479 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
481 /* Test a blit without keying */
482 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, 0, &fx);
483 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
485 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
486 ok(rc==DD_OK,"Lock returned: %x\n",rc);
487 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
488 lpData = ddsd2.lpSurface;
489 /* Should have copied src data unmodified to dst */
490 ok(lpData[0] == 0x000000FF &&
491 lpData[1] == 0x00000000 &&
492 lpData[2] == 0x00FF0000 &&
493 lpData[3] == 0x0000FF00 &&
494 lpData[4] == 0x00001100 &&
495 lpData[5] == 0x00110000, "Surface data after unkeyed blit does not match\n");
497 lpData[0] = 0x55555555;
498 lpData[1] = 0x55555555;
499 lpData[2] = 0x55555555;
500 lpData[3] = 0x55555555;
501 lpData[4] = 0x55555555;
502 lpData[5] = 0x55555555;
503 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
504 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
507 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
508 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
510 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
511 ok(rc==DD_OK,"Lock returned: %x\n",rc);
512 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
513 lpData = ddsd2.lpSurface;
515 ok(lpData[0] == 0x55555555 && /* Here the src key applied */
516 lpData[1] == 0x00000000 &&
517 lpData[2] == 0x00FF0000 &&
518 lpData[3] == 0x0000FF00 &&
519 lpData[4] == 0x00001100 &&
520 lpData[5] == 0x00110000, "Surface data after srckey blit does not match\n");
522 lpData[0] = 0x55555555;
523 lpData[1] = 0x55555555;
524 lpData[2] = 0x55555555;
525 lpData[3] = 0x55555555;
526 lpData[4] = 0x55555555;
527 lpData[5] = 0x55555555;
528 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
529 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
532 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
533 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
535 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
536 ok(rc==DD_OK,"Lock returned: %x\n",rc);
537 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
538 lpData = ddsd2.lpSurface;
540 ok(lpData[0] == 0x000000FF &&
541 lpData[1] == 0x00000000 &&
542 lpData[2] == 0x00FF0000 &&
543 lpData[3] == 0x0000FF00 &&
544 lpData[4] == 0x00001100 &&
545 lpData[5] == 0x55555555, /* Override key applies here */
546 "Surface data after src override key blit does not match\n");
548 lpData[0] = 0x55555555;
549 lpData[1] = 0x55555555;
550 lpData[2] = 0x55555555;
551 lpData[3] = 0x55555555;
552 lpData[4] = 0x55555555;
553 lpData[5] = 0x55555555;
554 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
555 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
557 /* Src override AND src key. That is not supposed to work */
558 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &fx);
559 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
561 /* Verify that the destination is unchanged */
562 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
563 ok(rc==DD_OK,"Lock returned: %x\n",rc);
564 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
565 lpData = ddsd2.lpSurface;
567 ok(lpData[0] == 0x55555555 &&
568 lpData[1] == 0x55555555 &&
569 lpData[2] == 0x55555555 &&
570 lpData[3] == 0x55555555 &&
571 lpData[4] == 0x55555555 &&
572 lpData[5] == 0x55555555, /* Override key applies here */
573 "Surface data after src key blit with override does not match\n");
575 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
576 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
577 lpData[2] = 0x00001100; /* Dest key in override */
578 lpData[3] = 0x00001100; /* Dest key in override */
579 lpData[4] = 0x00000000; /* Dest key in src surface */
580 lpData[5] = 0x00000000; /* Dest key in src surface */
581 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
582 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
585 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
586 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
588 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
589 ok(rc==DD_OK,"Lock returned: %x\n",rc);
590 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
591 lpData = ddsd2.lpSurface;
593 /* DirectDraw uses the dest blit key from the SOURCE surface ! */
594 ok(lpData[0] == 0x00ff0000 &&
595 lpData[1] == 0x00ff0000 &&
596 lpData[2] == 0x00001100 &&
597 lpData[3] == 0x00001100 &&
598 lpData[4] == 0x00001100 && /* Key applies here */
599 lpData[5] == 0x00110000, /* Key applies here */
600 "Surface data after dest key blit does not match\n");
602 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
603 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
604 lpData[2] = 0x00001100; /* Dest key in override */
605 lpData[3] = 0x00001100; /* Dest key in override */
606 lpData[4] = 0x00000000; /* Dest key in src surface */
607 lpData[5] = 0x00000000; /* Dest key in src surface */
608 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
609 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
611 /* Dest override key blit */
612 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
613 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
615 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
616 ok(rc==DD_OK,"Lock returned: %x\n",rc);
617 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
618 lpData = ddsd2.lpSurface;
620 ok(lpData[0] == 0x00FF0000 &&
621 lpData[1] == 0x00FF0000 &&
622 lpData[2] == 0x00FF0000 && /* Key applies here */
623 lpData[3] == 0x0000FF00 && /* Key applies here */
624 lpData[4] == 0x00000000 &&
625 lpData[5] == 0x00000000,
626 "Surface data after dest key override blit does not match\n");
628 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
629 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
630 lpData[2] = 0x00001100; /* Dest key in override */
631 lpData[3] = 0x00001100; /* Dest key in override */
632 lpData[4] = 0x00000000; /* Dest key in src surface */
633 lpData[5] = 0x00000000; /* Dest key in src surface */
634 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
635 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
637 /* Dest override key blit. Supposed to fail too */
638 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYDESTOVERRIDE, &fx);
639 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
641 /* Check for unchanged data */
642 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
643 ok(rc==DD_OK,"Lock returned: %x\n",rc);
644 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
645 lpData = ddsd2.lpSurface;
647 ok(lpData[0] == 0x00FF0000 &&
648 lpData[1] == 0x00FF0000 &&
649 lpData[2] == 0x00001100 && /* Key applies here */
650 lpData[3] == 0x00001100 && /* Key applies here */
651 lpData[4] == 0x00000000 &&
652 lpData[5] == 0x00000000,
653 "Surface data with dest key and dest override does not match\n");
655 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
656 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
657 lpData[2] = 0x00001100; /* Dest key in override */
658 lpData[3] = 0x00001100; /* Dest key in override */
659 lpData[4] = 0x00000000; /* Dest key in src surface */
660 lpData[5] = 0x00000000; /* Dest key in src surface */
661 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
662 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
664 /* Modify the source data a bit to give some more conclusive results */
665 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
666 ok(rc==DD_OK,"Lock returned: %x\n",rc);
667 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
668 lpData = ddsd2.lpSurface;
669 lpData[5] = 0x000000FF; /* Applies to src blt key in src surface */
670 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
671 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
673 /* Source and destination key */
674 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYSRC, &fx);
675 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
677 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
678 ok(rc==DD_OK,"Lock returned: %x\n",rc);
679 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
680 lpData = ddsd2.lpSurface;
682 ok(lpData[0] == 0x00FF0000 && /* Masked by Destination key */
683 lpData[1] == 0x00FF0000 && /* Masked by Destination key */
684 lpData[2] == 0x00001100 && /* Masked by Destination key */
685 lpData[3] == 0x00001100 && /* Masked by Destination key */
686 lpData[4] == 0x00001100 && /* Allowed by destination key, not masked by source key */
687 lpData[5] == 0x00000000, /* Allowed by dst key, but masked by source key */
688 "Surface data with src key and dest key blit does not match\n");
690 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
691 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
692 lpData[2] = 0x00001100; /* Dest key in override */
693 lpData[3] = 0x00001100; /* Dest key in override */
694 lpData[4] = 0x00000000; /* Dest key in src surface */
695 lpData[5] = 0x00000000; /* Dest key in src surface */
696 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
697 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
699 /* Override keys without ddbltfx parameter fail */
700 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, NULL);
701 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
702 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, NULL);
703 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
705 /* Try blitting without keys in the source surface*/
706 rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, NULL);
707 ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
708 rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_DESTBLT, NULL);
709 ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
711 /* That fails now. Do not bother to check that the data is unmodified */
712 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
713 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
715 /* Dest key blit still works. Which key is used this time??? */
716 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
717 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
719 /* With correctly passed override keys no key in the surface is needed.
720 * Again, the result was checked before, no need to do that again
722 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
723 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
724 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
725 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
727 IDirectDrawSurface_Release(lpSrc);
728 IDirectDrawSurface_Release(lpDst);
731 static void QueryInterface(void)
733 LPDIRECTDRAWSURFACE dsurface;
734 DDSURFACEDESC surface;
738 /* Create a surface */
739 ZeroMemory(&surface, sizeof(surface));
740 surface.dwSize = sizeof(surface);
741 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
742 surface.dwHeight = 10;
743 surface.dwWidth = 10;
744 ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
747 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
751 /* Call IUnknown::QueryInterface */
752 ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
753 ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %x\n", ret);
755 IDirectDrawSurface_Release(dsurface);
758 /* The following tests test which interface is returned by IDirectDrawSurfaceX::GetDDInterface.
759 * It uses refcounts to test that and compares the interface addresses. Partially fits here, and
760 * partially in the refcount test
763 static ULONG getref(IUnknown *iface)
765 IUnknown_AddRef(iface);
766 return IUnknown_Release(iface);
769 static void GetDDInterface_1(void)
771 LPDIRECTDRAWSURFACE dsurface;
772 LPDIRECTDRAWSURFACE2 dsurface2;
773 DDSURFACEDESC surface;
778 ULONG ref1, ref2, ref4, ref7;
781 /* Create a surface */
782 ZeroMemory(&surface, sizeof(surface));
783 surface.dwSize = sizeof(surface);
784 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
785 surface.dwHeight = 10;
786 surface.dwWidth = 10;
787 ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
790 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
793 ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
794 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
795 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
796 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
797 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
798 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
799 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
800 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
802 ref1 = getref((IUnknown *) lpDD);
803 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
804 ref2 = getref((IUnknown *) dd2);
805 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
806 ref4 = getref((IUnknown *) dd4);
807 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
808 ref7 = getref((IUnknown *) dd7);
809 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
812 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
813 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
814 ok(getref((IUnknown *) lpDD) == ref1 + 1, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
815 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
816 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
817 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
819 ok(dd == lpDD, "Returned interface pointer is not equal to the creation interface\n");
820 IUnknown_Release((IUnknown *) dd);
822 /* try a NULL pointer */
823 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, NULL);
824 ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
826 IDirectDraw_Release(dd2);
827 IDirectDraw_Release(dd4);
828 IDirectDraw_Release(dd7);
829 IDirectDrawSurface2_Release(dsurface2);
830 IDirectDrawSurface_Release(dsurface);
833 static void GetDDInterface_2(void)
835 LPDIRECTDRAWSURFACE dsurface;
836 LPDIRECTDRAWSURFACE2 dsurface2;
837 DDSURFACEDESC surface;
842 ULONG ref1, ref2, ref4, ref7;
845 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
846 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
847 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
848 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
849 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
850 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
852 /* Create a surface */
853 ZeroMemory(&surface, sizeof(surface));
854 surface.dwSize = sizeof(surface);
855 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
856 surface.dwHeight = 10;
857 surface.dwWidth = 10;
858 ret = IDirectDraw2_CreateSurface(dd2, &surface, &dsurface, NULL);
861 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
864 ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
865 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
867 ref1 = getref((IUnknown *) lpDD);
868 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
869 ref2 = getref((IUnknown *) dd2);
870 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
871 ref4 = getref((IUnknown *) dd4);
872 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
873 ref7 = getref((IUnknown *) dd7);
874 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
877 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
878 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
879 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
880 ok(getref((IUnknown *) dd2) == ref2 + 1, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
881 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
882 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
884 ok(dd == dd2, "Returned interface pointer is not equal to the creation interface\n");
885 IUnknown_Release((IUnknown *) dd);
887 IDirectDraw_Release(dd2);
888 IDirectDraw_Release(dd4);
889 IDirectDraw_Release(dd7);
890 IDirectDrawSurface2_Release(dsurface2);
891 IDirectDrawSurface_Release(dsurface);
894 static void GetDDInterface_4(void)
896 LPDIRECTDRAWSURFACE2 dsurface2;
897 LPDIRECTDRAWSURFACE4 dsurface4;
898 DDSURFACEDESC2 surface;
903 ULONG ref1, ref2, ref4, ref7;
906 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
907 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
908 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
909 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
910 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
911 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
913 /* Create a surface */
914 ZeroMemory(&surface, sizeof(surface));
915 surface.dwSize = sizeof(surface);
916 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
917 surface.dwHeight = 10;
918 surface.dwWidth = 10;
919 ret = IDirectDraw4_CreateSurface(dd4, &surface, &dsurface4, NULL);
922 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
925 ret = IDirectDrawSurface4_QueryInterface(dsurface4, &IID_IDirectDrawSurface2, (void **) &dsurface2);
926 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
928 ref1 = getref((IUnknown *) lpDD);
929 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
930 ref2 = getref((IUnknown *) dd2);
931 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
932 ref4 = getref((IUnknown *) dd4);
933 ok(ref4 == 2, "IDirectDraw4 refcount is %d\n", ref4);
934 ref7 = getref((IUnknown *) dd7);
935 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
937 ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
938 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
939 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
940 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
941 ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
942 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
944 ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
945 IUnknown_Release((IUnknown *) dd);
947 /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
948 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
949 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
950 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
951 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
952 ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
953 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
955 ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
956 IUnknown_Release((IUnknown *) dd);
958 IDirectDraw_Release(dd2);
959 IDirectDraw_Release(dd4);
960 IDirectDraw_Release(dd7);
961 IDirectDrawSurface4_Release(dsurface4);
962 IDirectDrawSurface2_Release(dsurface2);
965 static void GetDDInterface_7(void)
967 LPDIRECTDRAWSURFACE4 dsurface4;
968 LPDIRECTDRAWSURFACE7 dsurface7;
969 DDSURFACEDESC2 surface;
974 ULONG ref1, ref2, ref4, ref7;
977 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
978 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
979 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
980 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
981 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
982 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
984 /* Create a surface */
985 ZeroMemory(&surface, sizeof(surface));
986 surface.dwSize = sizeof(surface);
987 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
988 surface.dwHeight = 10;
989 surface.dwWidth = 10;
990 ret = IDirectDraw7_CreateSurface(dd7, &surface, &dsurface7, NULL);
993 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
996 ret = IDirectDrawSurface7_QueryInterface(dsurface7, &IID_IDirectDrawSurface4, (void **) &dsurface4);
997 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
999 ref1 = getref((IUnknown *) lpDD);
1000 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
1001 ref2 = getref((IUnknown *) dd2);
1002 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
1003 ref4 = getref((IUnknown *) dd4);
1004 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
1005 ref7 = getref((IUnknown *) dd7);
1006 ok(ref7 == 2, "IDirectDraw7 refcount is %d\n", ref7);
1008 ret = IDirectDrawSurface7_GetDDInterface(dsurface7, &dd);
1009 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1010 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1011 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1012 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1013 ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1015 ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1016 IUnknown_Release((IUnknown *) dd);
1018 /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
1019 ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
1020 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1021 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1022 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1023 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1024 ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1026 ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1027 IUnknown_Release((IUnknown *) dd);
1029 IDirectDraw_Release(dd2);
1030 IDirectDraw_Release(dd4);
1031 IDirectDraw_Release(dd7);
1032 IDirectDrawSurface4_Release(dsurface4);
1033 IDirectDrawSurface7_Release(dsurface7);
1036 static ULONG getRefcount(IUnknown *iface)
1038 IUnknown_AddRef(iface);
1039 return IUnknown_Release(iface);
1042 static void IFaceRefCount(void)
1044 LPDIRECTDRAWSURFACE surf;
1045 DDSURFACEDESC surface;
1047 IDirectDrawSurface2 *surf2;
1048 IDirectDrawSurface2 *surf2a;
1049 IDirectDrawSurface4 *surf4;
1050 IDirectDrawSurface7 *surf7a;
1051 IDirectDrawSurface7 *surf7b;
1052 IDirect3DTexture* tex;
1053 IDirect3DTexture2* tex2;
1054 IDirectDrawGammaControl* gamma;
1057 /* Create a surface */
1058 ZeroMemory(&surface, sizeof(surface));
1059 surface.dwSize = sizeof(surface);
1060 surface.dwFlags = DDSD_CAPS;
1061 surface.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1062 ret = IDirectDraw_CreateSurface(lpDD, &surface, &surf, NULL);
1066 ok(FALSE, "Could not create surface, skipping test\n");
1070 ref = getRefcount((IUnknown *) surf);
1071 ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
1073 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
1074 ref = getRefcount((IUnknown *) surf);
1075 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
1076 ref = getRefcount((IUnknown *) surf2);
1077 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* This should also be one */
1079 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2a);
1080 ref = getRefcount((IUnknown *) surf2);
1081 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref); /* Surf2's refcount should be 2 now, but surf should be 1 */
1082 ref = getRefcount((IUnknown *) surf);
1083 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1085 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface4, (void **) &surf4);
1086 ref = getRefcount((IUnknown *) surf4);
1087 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1089 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7a);
1090 ref = getRefcount((IUnknown *) surf7a);
1091 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1093 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7b);
1094 ref = getRefcount((IUnknown *) surf7b);
1095 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1097 /* IDirect3DTexture interface (unlike the others) alters the original IDirectDrawSurface ref count */
1098 ret = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture, (void **) &tex);
1101 ref = getRefcount((IUnknown *) tex);
1102 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1103 ref = getRefcount((IUnknown *) surf);
1104 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1106 IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture2, (void **) &tex2);
1107 ref = getRefcount((IUnknown *) tex);
1108 todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1109 ref = getRefcount((IUnknown *) tex2);
1110 todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1111 ref = getRefcount((IUnknown *) surf);
1112 todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1114 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawGammaControl, (void **) &gamma);
1115 ref = getRefcount((IUnknown *) gamma);
1116 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1118 ref = IDirect3DTexture2_Release(tex2); /* Release the texture */
1119 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1120 ref = getRefcount((IUnknown *) surf);
1121 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1123 ref = IDirect3DTexture_Release(tex); /* Release the texture */
1124 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1125 ref = getRefcount((IUnknown *) surf);
1126 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1128 ref = IDirectDrawGammaControl_Release(gamma); /* Release the gamma control */
1129 todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1132 ref = IDirectDrawSurface2_Release(surf2); /* Release one of the 2 surf2 interfaces */
1133 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1135 ref = IDirectDrawSurface2_Release(surf2a); /* Release the other */
1136 todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1138 ref = IDirectDrawSurface4_Release(surf4);
1139 todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1141 ref = IDirectDrawSurface7_Release(surf7a);
1142 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1144 ref = IDirectDrawSurface7_Release(surf7b);
1145 todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1147 ref = IDirectDrawSurface_Release(surf);
1148 ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1151 #define MAXEXPECTED 8 /* Can match up to 8 expected surfaces */
1154 IDirectDrawSurface *expected[MAXEXPECTED];
1158 static HRESULT WINAPI enumCB(IDirectDrawSurface *surf, DDSURFACEDESC *desc, void *ctx)
1163 for(i = 0; i < MAXEXPECTED; i++)
1165 if(((struct enumstruct *)ctx)->expected[i] == surf) found = TRUE;
1168 ok(found, "Unexpected surface %p enumerated\n", surf);
1169 ((struct enumstruct *)ctx)->count++;
1170 IDirectDrawSurface_Release(surf);
1171 return DDENUMRET_OK;
1174 static void EnumTest(void)
1178 IDirectDrawSurface *surface;
1179 struct enumstruct ctx;
1181 ddsd.dwSize = sizeof(ddsd);
1182 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1183 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1184 U2(ddsd).dwMipMapCount = 3;
1187 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
1188 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
1190 memset(&ctx, 0, sizeof(ctx));
1191 ctx.expected[0] = surface;
1192 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[0], &ddsd.ddsCaps, &ctx.expected[1]);
1193 ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1194 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[1], &ddsd.ddsCaps, &ctx.expected[2]);
1195 ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1196 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[2], &ddsd.ddsCaps, &ctx.expected[3]);
1197 ok(rc == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", rc);
1198 ok(!ctx.expected[3], "expected NULL pointer\n");
1201 rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, &ddsd, &ctx, enumCB);
1202 ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
1203 ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
1205 IDirectDrawSurface_Release(ctx.expected[2]);
1206 IDirectDrawSurface_Release(ctx.expected[1]);
1207 IDirectDrawSurface_Release(surface);
1210 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1212 UINT *num = context;
1214 IDirectDrawSurface_Release(surface);
1215 return DDENUMRET_OK;
1218 static void AttachmentTest7(void)
1222 IDirectDrawSurface7 *surface1, *surface2, *surface3, *surface4;
1223 DDSURFACEDESC2 ddsd, ddsd2;
1225 DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0}, caps2 = {DDSCAPS_BACKBUFFER,0,0,0};
1226 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1228 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1229 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1231 memset(&ddsd, 0, sizeof(ddsd));
1232 ddsd.dwSize = sizeof(ddsd);
1233 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1234 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1235 U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1237 ddsd.dwHeight = 128;
1238 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1239 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1243 IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1244 ok(num == 1, "Mipmap root has %d surfaces attached, expected 1\n", num);
1248 hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1249 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1251 IDirectDrawSurface7_EnumAttachedSurfaces(surface2, &num, SurfaceCounter);
1252 ok(num == 1, "First mip level has %d surfaces attached, expected 1\n", num);
1256 hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1257 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1258 IDirectDrawSurface7_Release(surface2);
1260 IDirectDrawSurface7_EnumAttachedSurfaces(surface3, &num, SurfaceCounter);
1261 ok(num == 0, "Second mip level has %d surfaces attached, expected 1\n", num);
1263 /* Mip level 3 is still needed */
1264 hr = IDirectDrawSurface7_GetAttachedSurface(surface3, &caps, &surface4);
1265 ok(hr == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", hr);
1266 ok(!surface4, "expected NULL pointer\n");
1268 /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1269 memset(&ddsd, 0, sizeof(ddsd));
1270 ddsd.dwSize = sizeof(ddsd);
1271 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1272 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1275 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1276 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1278 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1279 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1280 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1281 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1282 hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1283 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1284 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1285 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1287 IDirectDrawSurface7_Release(surface2);
1289 memset(&ddsd, 0, sizeof(ddsd));
1290 ddsd.dwSize = sizeof(ddsd);
1291 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1292 ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1295 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1296 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1298 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1299 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1300 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1301 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1302 hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1303 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1304 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1305 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1307 IDirectDrawSurface7_Release(surface3);
1308 IDirectDrawSurface7_Release(surface2);
1309 IDirectDrawSurface7_Release(surface1);
1311 hr = IDirectDraw7_SetCooperativeLevel(dd7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1312 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1314 memset(&ddsd, 0, sizeof(ddsd));
1315 ddsd.dwSize = sizeof(ddsd);
1316 ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
1317 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
1318 ddsd.dwBackBufferCount = 2;
1319 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1320 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1322 /* backbuffer surfaces must not have dwBackBufferCount set */
1323 ddsd2.dwSize = sizeof(ddsd2);
1324 hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps2, &surface2);
1325 ok(hr==DD_OK,"GetAttachedSurface returned: %x\n", hr);
1326 hr = IDirectDrawSurface7_GetSurfaceDesc(surface2, &ddsd2);
1327 ok(hr==DD_OK,"GetSurfaceDesc returned: %x\n", hr);
1328 ok(ddsd2.dwBackBufferCount==0,"backbuffer surface has dwBackBufferCount==%u\n", ddsd2.dwBackBufferCount);
1331 IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1332 ok(num == 1, "Primary surface has %d surfaces attached, expected 1\n", num);
1333 IDirectDrawSurface7_Release(surface1);
1335 /* Those are some invalid descriptions, no need to test attachments with them */
1336 memset(&ddsd, 0, sizeof(ddsd));
1337 ddsd.dwSize = sizeof(ddsd);
1338 ddsd.dwFlags = DDSD_CAPS;
1339 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1340 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1341 ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1342 memset(&ddsd, 0, sizeof(ddsd));
1343 ddsd.dwSize = sizeof(ddsd);
1344 ddsd.dwFlags = DDSD_CAPS;
1345 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1346 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1347 ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1349 /* Try a single primary and two offscreen plain surfaces */
1350 memset(&ddsd, 0, sizeof(ddsd));
1351 ddsd.dwSize = sizeof(ddsd);
1352 ddsd.dwFlags = DDSD_CAPS;
1353 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1354 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1355 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1357 memset(&ddsd, 0, sizeof(ddsd));
1358 ddsd.dwSize = sizeof(ddsd);
1359 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1360 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1361 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1362 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1363 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1364 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1366 memset(&ddsd, 0, sizeof(ddsd));
1367 ddsd.dwSize = sizeof(ddsd);
1368 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1369 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1370 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1371 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1372 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface3, NULL);
1373 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1375 /* This one has a different size */
1376 memset(&ddsd, 0, sizeof(ddsd));
1377 ddsd.dwSize = sizeof(ddsd);
1378 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1379 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1381 ddsd.dwHeight = 128;
1382 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface4, NULL);
1383 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1385 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1386 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1387 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1388 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1389 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1390 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1391 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1392 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1393 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1394 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1396 IDirectDrawSurface7_Release(surface4);
1397 IDirectDrawSurface7_Release(surface3);
1398 IDirectDrawSurface7_Release(surface2);
1399 IDirectDrawSurface7_Release(surface1);
1401 hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL);
1402 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1403 IDirectDraw7_Release(dd7);
1406 static void AttachmentTest(void)
1409 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
1411 DDSCAPS caps = {DDSCAPS_TEXTURE};
1412 BOOL refrast = FALSE;
1413 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1415 memset(&ddsd, 0, sizeof(ddsd));
1416 ddsd.dwSize = sizeof(ddsd);
1417 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1418 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1419 U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1421 ddsd.dwHeight = 128;
1422 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1423 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1425 hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1426 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1427 hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1428 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1430 /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1431 memset(&ddsd, 0, sizeof(ddsd));
1432 ddsd.dwSize = sizeof(ddsd);
1433 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1434 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1437 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1438 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1440 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1441 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1442 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1443 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1444 hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
1445 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1446 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1447 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1448 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
1449 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 64x64 texture sublevel returned %08x\n", hr);
1450 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1451 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 texture returned %08x\n", hr);
1453 IDirectDrawSurface7_Release(surface4);
1455 memset(&ddsd, 0, sizeof(ddsd));
1456 ddsd.dwSize = sizeof(ddsd);
1457 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1458 ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1461 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1462 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1464 if (SUCCEEDED(IDirectDrawSurface7_AddAttachedSurface(surface1, surface4)))
1466 IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1470 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4); /* Succeeds on refrast */
1472 ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1474 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1475 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1477 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1); /* Succeeds on refrast */
1479 ok(hr == S_OK, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1481 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1482 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface1);
1484 hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4); /* Succeeds on refrast */
1486 ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1488 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1489 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface3, 0, surface4);
1491 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1492 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1493 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface3);
1495 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4); /* Succeeds on refrast */
1497 ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1499 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1500 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface2, 0, surface4);
1502 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1503 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 offscreen plain surface returned %08x\n", hr);
1504 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface2);
1506 IDirectDrawSurface7_Release(surface4);
1507 IDirectDrawSurface7_Release(surface3);
1508 IDirectDrawSurface7_Release(surface2);
1509 IDirectDrawSurface7_Release(surface1);
1511 hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1512 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1514 /* Creating a back buffer as-is, is not allowed. No need to perform attachment tests */
1515 memset(&ddsd, 0, sizeof(ddsd));
1516 ddsd.dwSize = sizeof(ddsd);
1517 ddsd.dwFlags = DDSD_CAPS;
1518 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1519 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1520 ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1521 /* This old ddraw version happily creates explicit front buffers */
1522 memset(&ddsd, 0, sizeof(ddsd));
1523 ddsd.dwSize = sizeof(ddsd);
1524 ddsd.dwFlags = DDSD_CAPS;
1525 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1526 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1527 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1528 IDirectDrawSurface_Release(surface1);
1530 /* Try a single primary and two offscreen plain surfaces */
1531 memset(&ddsd, 0, sizeof(ddsd));
1532 ddsd.dwSize = sizeof(ddsd);
1533 ddsd.dwFlags = DDSD_CAPS;
1534 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1535 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1536 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1538 memset(&ddsd, 0, sizeof(ddsd));
1539 ddsd.dwSize = sizeof(ddsd);
1540 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1541 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1542 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1543 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1544 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1545 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1547 memset(&ddsd, 0, sizeof(ddsd));
1548 ddsd.dwSize = sizeof(ddsd);
1549 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1550 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1551 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1552 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1553 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
1554 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1556 /* This one has a different size */
1557 memset(&ddsd, 0, sizeof(ddsd));
1558 ddsd.dwSize = sizeof(ddsd);
1559 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1560 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1562 ddsd.dwHeight = 128;
1563 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1564 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1566 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
1567 ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1568 "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1571 /* Try the reverse without detaching first */
1572 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1573 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
1574 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1575 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1577 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1578 ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1579 "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1582 /* Try to detach reversed */
1583 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1584 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
1585 /* Now the proper detach */
1586 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
1587 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1589 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3); /* Fails on refrast */
1590 ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1591 "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1594 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
1595 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1597 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
1598 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1599 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
1600 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1602 IDirectDrawSurface_Release(surface4);
1603 IDirectDrawSurface_Release(surface3);
1604 IDirectDrawSurface_Release(surface2);
1605 IDirectDrawSurface_Release(surface1);
1607 hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
1608 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1610 DestroyWindow(window);
1615 DWORD width, height;
1620 static HRESULT WINAPI CubeTestLvl2Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1622 UINT *mips = context;
1625 IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1629 return DDENUMRET_OK;
1632 static HRESULT WINAPI CubeTestLvl1Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1635 UINT *num = context;
1636 static const struct compare expected[] =
1640 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1641 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ,
1646 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1647 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ,
1652 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1653 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY,
1658 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1659 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY,
1664 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1665 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX,
1669 64, 64, /* This is the first mipmap */
1670 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1671 DDSCAPS2_MIPMAPSUBLEVEL | DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX,
1677 IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1681 ok(desc->dwWidth == expected[*num].width, "Surface width is %d expected %d\n", desc->dwWidth, expected[*num].width);
1682 ok(desc->dwHeight == expected[*num].height, "Surface height is %d expected %d\n", desc->dwHeight, expected[*num].height);
1683 ok(desc->ddsCaps.dwCaps == expected[*num].caps, "Surface caps are %08x expected %08x\n", desc->ddsCaps.dwCaps, expected[*num].caps);
1684 ok(desc->ddsCaps.dwCaps2 == expected[*num].caps2, "Surface caps2 are %08x expected %08x\n", desc->ddsCaps.dwCaps2, expected[*num].caps2);
1685 ok(mips == expected[*num].mips, "Surface has %d mipmaps, expected %d\n", mips, expected[*num].mips);
1689 IDirectDrawSurface7_Release(surface);
1691 return DDENUMRET_OK;
1694 static void CubeMapTest(void)
1696 IDirectDraw7 *dd7 = NULL;
1697 IDirectDrawSurface7 *cubemap = NULL;
1698 DDSURFACEDESC2 ddsd;
1701 struct enumstruct ctx;
1703 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1704 ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1705 if (FAILED(hr)) goto err;
1707 memset(&ddsd, 0, sizeof(ddsd));
1708 ddsd.dwSize = sizeof(ddsd);
1709 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1710 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1712 ddsd.dwHeight = 128;
1713 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1714 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1717 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1718 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1719 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1720 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1721 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1723 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1726 skip("Can't create cubemap surface\n");
1730 hr = IDirectDrawSurface7_GetSurfaceDesc(cubemap, &ddsd);
1731 ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
1732 ok(ddsd.ddsCaps.dwCaps == (DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX),
1733 "Root Caps are %08x\n", ddsd.ddsCaps.dwCaps);
1734 ok(ddsd.ddsCaps.dwCaps2 == (DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP),
1735 "Root Caps2 are %08x\n", ddsd.ddsCaps.dwCaps2);
1737 IDirectDrawSurface7_EnumAttachedSurfaces(cubemap,
1740 ok(num == 6, "Surface has %d attachments\n", num);
1741 IDirectDrawSurface7_Release(cubemap);
1743 /* What happens if I do not specify any faces? */
1744 memset(&ddsd, 0, sizeof(ddsd));
1745 ddsd.dwSize = sizeof(ddsd);
1746 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1747 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1749 ddsd.dwHeight = 128;
1750 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1751 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP;
1754 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1755 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1756 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1757 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1758 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1760 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1761 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7::CreateSurface asking for a cube map without faces returned %08x\n", hr);
1763 /* Cube map faces without a cube map? */
1764 memset(&ddsd, 0, sizeof(ddsd));
1765 ddsd.dwSize = sizeof(ddsd);
1766 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1767 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1769 ddsd.dwHeight = 128;
1770 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1771 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_ALLFACES;
1774 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1775 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1776 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1777 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1778 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1780 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1781 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1783 memset(&ddsd, 0, sizeof(ddsd));
1784 ddsd.dwSize = sizeof(ddsd);
1785 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1786 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1788 ddsd.dwHeight = 128;
1789 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1790 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEX;
1793 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1794 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1795 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1796 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1797 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1799 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1800 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1802 /* Make sure everything is cleaned up properly. Use the enumSurfaces test infrastructure */
1803 memset(&ctx, 0, sizeof(ctx));
1804 memset(&ddsd, 0, sizeof(ddsd));
1805 ddsd.dwSize = sizeof(DDSURFACEDESC);
1806 hr = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, (DDSURFACEDESC *) &ddsd, (void *) &ctx, enumCB);
1807 ok(hr == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", hr);
1808 ok(ctx.count == 0, "%d surfaces enumerated, expected 0\n", ctx.count);
1811 if (dd7) IDirectDraw7_Release(dd7);
1814 static void test_lockrect_invalid(void)
1827 {68, 60, 60, 68}, /* left > right */
1828 {60, 68, 68, 60}, /* top > bottom */
1829 {-8, 60, 0, 68}, /* left < surface */
1830 {60, -8, 68, 0}, /* top < surface */
1831 {-16, 60, -8, 68}, /* right < surface */
1832 {60, -16, 68, -8}, /* bottom < surface */
1833 {60, 60, 136, 68}, /* right > surface */
1834 {60, 60, 68, 136}, /* bottom > surface */
1835 {136, 60, 144, 68}, /* left > surface */
1836 {60, 136, 68, 144}, /* top > surface */
1839 const DWORD dds_caps[] = {
1840 DDSCAPS_OFFSCREENPLAIN
1843 for (j = 0; j < (sizeof(dds_caps) / sizeof(*dds_caps)); ++j)
1845 IDirectDrawSurface *surface = 0;
1846 DDSURFACEDESC surface_desc = {0};
1847 DDSURFACEDESC locked_desc = {0};
1850 surface_desc.dwSize = sizeof(surface_desc);
1851 surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
1852 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1853 surface_desc.ddsCaps.dwCaps = dds_caps[j];
1854 surface_desc.dwWidth = 128;
1855 surface_desc.dwHeight = 128;
1856 surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
1857 U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
1858 U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xFF0000;
1859 U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00FF00;
1860 U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000FF;
1862 hr = IDirectDraw_CreateSurface(lpDD, &surface_desc, &surface, NULL);
1863 ok(SUCCEEDED(hr), "CreateSurface failed (0x%08x)\n", hr);
1865 skip("failed to create surface\n");
1869 for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i)
1871 RECT *rect = &valid[i];
1873 memset(&locked_desc, 0, sizeof(locked_desc));
1874 locked_desc.dwSize = sizeof(locked_desc);
1876 hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1877 ok(SUCCEEDED(hr), "Lock failed (0x%08x) for rect [%d, %d]->[%d, %d]\n",
1878 hr, rect->left, rect->top, rect->right, rect->bottom);
1880 hr = IDirectDrawSurface_Unlock(surface, NULL);
1881 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1884 for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i)
1886 RECT *rect = &invalid[i];
1888 memset(&locked_desc, 1, sizeof(locked_desc));
1889 locked_desc.dwSize = sizeof(locked_desc);
1891 hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1892 ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for rect [%d, %d]->[%d, %d]"
1893 ", expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, rect->left, rect->top,
1894 rect->right, rect->bottom, DDERR_INVALIDPARAMS);
1895 ok(!locked_desc.lpSurface, "IDirectDrawSurface_Lock did not set lpSurface in the surface desc to zero.\n");
1898 hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1899 ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = NULL) failed (0x%08x)\n", hr);
1900 hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1901 ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned 0x%08x\n", hr);
1903 hr = IDirectDrawSurface_Unlock(surface, NULL);
1904 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1906 hr = IDirectDrawSurface_Unlock(surface, NULL);
1907 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1909 memset(&locked_desc, 0, sizeof(locked_desc));
1910 locked_desc.dwSize = sizeof(locked_desc);
1911 hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1912 ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1913 valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1914 hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1915 ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1916 valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1918 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
1919 * Afterwards unlocking the surface fails(NULL rectangle, and both locked rectangles
1922 hr = IDirectDrawSurface_Unlock(surface, NULL);
1923 ok(hr == DD_OK, "Unlock returned (0x%08x)\n", hr);
1925 IDirectDrawSurface_Release(surface);
1929 static void CompressedTest(void)
1932 IDirectDrawSurface7 *surface;
1933 DDSURFACEDESC2 ddsd, ddsd2;
1934 IDirectDraw7 *dd7 = NULL;
1935 RECT r = { 0, 0, 128, 128 };
1936 RECT r2 = { 32, 32, 64, 64 };
1938 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1939 ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1941 memset(&ddsd, 0, sizeof(ddsd));
1942 ddsd.dwSize = sizeof(ddsd);
1943 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1944 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1946 ddsd.dwHeight = 128;
1947 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
1948 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
1949 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1951 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1952 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1954 skip("failed to create surface\n");
1958 memset(&ddsd2, 0, sizeof(ddsd2));
1959 ddsd2.dwSize = sizeof(ddsd2);
1960 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1961 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1962 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1964 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1965 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1966 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1967 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1968 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1969 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1970 ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1971 ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1972 IDirectDrawSurface7_Release(surface);
1974 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1975 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1976 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1978 skip("failed to create surface\n");
1982 memset(&ddsd2, 0, sizeof(ddsd2));
1983 ddsd2.dwSize = sizeof(ddsd2);
1984 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1985 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1986 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1988 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1989 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1990 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1991 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1992 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1993 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1994 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1995 IDirectDrawSurface7_Release(surface);
1997 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1998 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1999 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2001 skip("failed to create surface\n");
2005 memset(&ddsd2, 0, sizeof(ddsd2));
2006 ddsd2.dwSize = sizeof(ddsd2);
2007 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2008 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2009 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2011 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2012 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2013 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2014 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2015 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2016 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2017 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2018 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2020 memset(&ddsd2, 0, sizeof(ddsd2));
2021 ddsd2.dwSize = sizeof(ddsd2);
2022 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2024 /* Show that the description is not changed when locking the surface. What is really interesting
2025 * about this is that DDSD_LPSURFACE isn't set.
2027 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2028 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2030 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2031 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2032 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2033 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2034 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2035 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2036 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2037 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2039 hr = IDirectDrawSurface7_Unlock(surface, NULL);
2040 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2042 /* Now what about a locking rect? */
2043 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2044 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2046 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2047 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2048 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2049 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2050 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2051 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2052 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2053 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2055 hr = IDirectDrawSurface7_Unlock(surface, &r);
2056 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2058 /* Now what about a different locking offset? */
2059 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2060 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2062 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2063 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2064 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2065 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2066 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2067 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2068 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2069 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2071 hr = IDirectDrawSurface7_Unlock(surface, &r2);
2072 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2073 IDirectDrawSurface7_Release(surface);
2075 /* Try this with video memory. A kind of surprise. It still has the LINEARSIZE flag set,
2076 * but seems to have a pitch instead.
2078 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
2079 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2081 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2082 ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW || hr == DDERR_INVALIDPARAMS ||
2083 broken(hr == DDERR_NODIRECTDRAWHW), "CreateSurface returned %08x\n", hr);
2085 /* Not supported everywhere */
2088 memset(&ddsd2, 0, sizeof(ddsd2));
2089 ddsd2.dwSize = sizeof(ddsd2);
2090 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2091 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2092 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2094 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2095 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2096 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2097 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2098 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2099 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2100 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2101 ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2102 IDirectDrawSurface7_Release(surface);
2104 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2105 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2106 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2108 memset(&ddsd2, 0, sizeof(ddsd2));
2109 ddsd2.dwSize = sizeof(ddsd2);
2110 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2111 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2112 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2114 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2115 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2116 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2117 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2118 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2119 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2120 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2121 IDirectDrawSurface7_Release(surface);
2123 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2124 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2125 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2127 memset(&ddsd2, 0, sizeof(ddsd2));
2128 ddsd2.dwSize = sizeof(ddsd2);
2129 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2130 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2131 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2133 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2134 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2135 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2136 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2137 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2138 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2139 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2140 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2142 memset(&ddsd2, 0, sizeof(ddsd2));
2143 ddsd2.dwSize = sizeof(ddsd2);
2144 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2146 /* Show that the description is not changed when locking the surface. What is really interesting
2147 * about this is that DDSD_LPSURFACE isn't set.
2149 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2150 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2152 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2153 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2154 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2155 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2156 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2157 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2158 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2159 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2161 hr = IDirectDrawSurface7_Unlock(surface, NULL);
2162 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2164 /* Now what about a locking rect? */
2165 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2166 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2168 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2169 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2170 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2171 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2172 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2173 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2174 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2175 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2177 hr = IDirectDrawSurface7_Unlock(surface, &r);
2178 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2180 /* Now what about a different locking offset? */
2181 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2182 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2184 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2185 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2186 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2187 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2188 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2189 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2190 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2191 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2193 hr = IDirectDrawSurface7_Unlock(surface, &r2);
2194 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2196 IDirectDrawSurface7_Release(surface);
2200 skip("Hardware DXTN textures not supported\n");
2203 /* What happens to managed textures? Interestingly, Windows reports them as being in system
2204 * memory. The linear size fits again.
2206 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2207 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
2208 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2210 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2211 ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW, "CreateSurface returned %08x\n", hr);
2213 /* Not supported everywhere */
2216 memset(&ddsd2, 0, sizeof(ddsd2));
2217 ddsd2.dwSize = sizeof(ddsd2);
2218 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2219 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2220 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2222 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2223 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2224 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2225 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2226 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2227 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2228 ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2229 ok(ddsd2.ddsCaps.dwCaps2 == DDSCAPS2_TEXTUREMANAGE, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2230 IDirectDrawSurface7_Release(surface);
2232 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2233 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2234 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2236 memset(&ddsd2, 0, sizeof(ddsd2));
2237 ddsd2.dwSize = sizeof(ddsd2);
2238 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2239 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2240 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2242 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2243 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2244 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2245 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2246 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2247 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2248 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2249 IDirectDrawSurface7_Release(surface);
2251 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2252 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2253 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2255 memset(&ddsd2, 0, sizeof(ddsd2));
2256 ddsd2.dwSize = sizeof(ddsd2);
2257 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2258 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2259 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2261 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2262 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2263 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2264 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2265 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2266 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2267 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2268 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2270 memset(&ddsd2, 0, sizeof(ddsd2));
2271 ddsd2.dwSize = sizeof(ddsd2);
2272 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2274 /* Show that the description is not changed when locking the surface. What is really interesting
2275 * about this is that DDSD_LPSURFACE isn't set.
2277 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2278 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2280 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2281 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2282 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2283 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2284 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2285 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2286 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2287 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2289 hr = IDirectDrawSurface7_Unlock(surface, NULL);
2290 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2292 /* Now what about a locking rect? */
2293 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2294 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2296 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2297 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2298 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2299 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2300 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2301 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2302 ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2303 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2305 hr = IDirectDrawSurface7_Unlock(surface, &r);
2306 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2308 /* Now what about a different locking offset? */
2309 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2310 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2312 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2313 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2314 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2315 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2316 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2317 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2318 ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2319 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2321 hr = IDirectDrawSurface7_Unlock(surface, &r2);
2322 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2324 IDirectDrawSurface7_Release(surface);
2328 skip("Hardware DXTN textures not supported\n");
2331 IDirectDraw7_Release(dd7);
2334 static void SizeTest(void)
2336 LPDIRECTDRAWSURFACE dsurface = NULL;
2339 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2341 /* Create an offscreen surface surface without a size */
2342 ZeroMemory(&desc, sizeof(desc));
2343 desc.dwSize = sizeof(desc);
2344 desc.dwFlags = DDSD_CAPS;
2345 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2346 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2347 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without a size info returned %08x (dsurface=%p)\n", ret, dsurface);
2350 trace("Surface at %p\n", dsurface);
2351 IDirectDrawSurface_Release(dsurface);
2355 /* Create an offscreen surface surface with only a width parameter */
2356 ZeroMemory(&desc, sizeof(desc));
2357 desc.dwSize = sizeof(desc);
2358 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH;
2359 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2361 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2362 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without hight info returned %08x\n", ret);
2365 IDirectDrawSurface_Release(dsurface);
2369 /* Create an offscreen surface surface with only a height parameter */
2370 ZeroMemory(&desc, sizeof(desc));
2371 desc.dwSize = sizeof(desc);
2372 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT;
2373 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2374 desc.dwHeight = 128;
2375 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2376 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without width info returned %08x\n", ret);
2379 IDirectDrawSurface_Release(dsurface);
2384 ZeroMemory(&desc, sizeof(desc));
2385 desc.dwSize = sizeof(desc);
2386 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2387 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2388 desc.dwHeight = 128;
2390 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2391 ok(ret == DD_OK, "Creating an offscreen plain surface with width and height info returned %08x\n", ret);
2394 IDirectDrawSurface_Release(dsurface);
2398 /* Test a primary surface size */
2399 ret = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_NORMAL);
2400 ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2402 ZeroMemory(&desc, sizeof(desc));
2403 desc.dwSize = sizeof(desc);
2404 desc.dwFlags = DDSD_CAPS;
2405 desc.ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
2406 desc.dwHeight = 128; /* Keep them set to check what happens */
2407 desc.dwWidth = 128; /* Keep them set to check what happens */
2408 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2409 ok(ret == DD_OK, "Creating a primary surface without width and height info returned %08x\n", ret);
2412 ret = IDirectDrawSurface_GetSurfaceDesc(dsurface, &desc);
2413 ok(ret == DD_OK, "GetSurfaceDesc returned %x\n", ret);
2415 IDirectDrawSurface_Release(dsurface);
2418 ok(desc.dwFlags & DDSD_WIDTH, "Primary surface doesn't have width set\n");
2419 ok(desc.dwFlags & DDSD_HEIGHT, "Primary surface doesn't have height set\n");
2420 ok(desc.dwWidth == GetSystemMetrics(SM_CXSCREEN), "Surface width differs from screen width\n");
2421 ok(desc.dwHeight == GetSystemMetrics(SM_CYSCREEN), "Surface height differs from screen height\n");
2423 ret = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
2424 ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2427 static void PrivateDataTest(void)
2430 IDirectDrawSurface7 *surface7 = NULL;
2431 IDirectDrawSurface *surface = NULL;
2435 DWORD size = sizeof(IUnknown *);
2437 ZeroMemory(&desc, sizeof(desc));
2438 desc.dwSize = sizeof(desc);
2439 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2440 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2441 desc.dwHeight = 128;
2443 hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface, NULL);
2444 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2449 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **) &surface7);
2450 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2453 IDirectDrawSurface_Release(surface);
2458 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 0, DDSPD_IUNKNOWNPOINTER);
2459 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2460 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 5, DDSPD_IUNKNOWNPOINTER);
2461 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2462 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *) * 2, DDSPD_IUNKNOWNPOINTER);
2463 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2465 ref = getref((IUnknown *) lpDD);
2466 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2467 ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2468 ref2 = getref((IUnknown *) lpDD);
2469 ok(ref2 == ref + 1, "Object reference is %d, expected %d\n", ref2, ref + 1);
2470 hr = IDirectDrawSurface7_FreePrivateData(surface7, &IID_IDirectDrawSurface7);
2471 ok(SUCCEEDED(hr), "IDirectDrawSurface7_FreePrivateData returned %#x.\n", hr);
2472 ref2 = getref((IUnknown *) lpDD);
2473 ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2475 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2476 ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2477 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, surface7, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2478 ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2479 ref2 = getref((IUnknown *) lpDD);
2480 ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2482 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2483 ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2484 hr = IDirectDrawSurface7_GetPrivateData(surface7, &IID_IDirectDrawSurface7, &ptr, &size);
2485 ok(hr == DD_OK, "IDirectDrawSurface7_GetPrivateData failed with %08x\n", hr);
2486 ref2 = getref((IUnknown *) lpDD);
2487 /* Object is NOT being addrefed */
2488 ok(ptr == (IUnknown *) lpDD, "Returned interface pointer is %p, expected %p\n", ptr, lpDD);
2489 ok(ref2 == ref + 1, "Object reference is %d, expected %d. ptr at %p, orig at %p\n", ref2, ref + 1, ptr, lpDD);
2491 IDirectDrawSurface_Release(surface);
2492 IDirectDrawSurface7_Release(surface7);
2494 /* Destroying the surface frees the held reference */
2495 ref2 = getref((IUnknown *) lpDD);
2496 ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2499 static void BltParamTest(void)
2501 IDirectDrawSurface *surface1 = NULL, *surface2 = NULL;
2505 RECT valid = {10, 10, 20, 20};
2506 RECT invalid1 = {20, 10, 10, 20};
2507 RECT invalid2 = {20, 20, 20, 20};
2508 RECT invalid3 = {-1, -1, 20, 20};
2509 RECT invalid4 = {60, 60, 70, 70};
2511 memset(&desc, 0, sizeof(desc));
2512 desc.dwSize = sizeof(desc);
2513 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2514 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2515 desc.dwHeight = 128;
2517 hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface1, NULL);
2518 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2522 hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface2, NULL);
2523 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2528 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, NULL, NULL, 0);
2529 ok(hr == DD_OK, "BltFast from NULL surface returned %08x\n", hr);
2531 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, NULL, 0);
2532 ok(hr == DD_OK, "BltFast from smaller to bigger surface returned %08x\n", hr);
2533 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, NULL, 0);
2534 ok(hr == DDERR_INVALIDRECT, "BltFast from bigger to smaller surface returned %08x\n", hr);
2535 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &valid, 0);
2536 ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle returned %08x\n", hr);
2537 hr = IDirectDrawSurface_BltFast(surface2, 60, 60, surface1, &valid, 0);
2538 ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2539 hr = IDirectDrawSurface_BltFast(surface1, 90, 90, surface2, NULL, 0);
2540 ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2542 hr = IDirectDrawSurface_BltFast(surface1, -10, 0, surface2, NULL, 0);
2543 ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
2544 hr = IDirectDrawSurface_BltFast(surface1, 0, -10, surface2, NULL, 0);
2545 ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
2546 hr = IDirectDrawSurface_BltFast(surface2, 20, 20, surface1, &valid, 0);
2547 ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle and offset returned %08x\n", hr);
2549 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid1, 0);
2550 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 1 returned %08x\n", hr);
2551 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid2, 0);
2552 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 2 returned %08x\n", hr);
2553 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid3, 0);
2554 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2555 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, &invalid4, 0);
2556 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2557 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface1, NULL, 0);
2558 ok(hr == DD_OK, "BltFast blitting a surface onto itself returned %08x\n", hr);
2560 /* Blt(non-fast) tests */
2561 memset(&BltFx, 0, sizeof(BltFx));
2562 BltFx.dwSize = sizeof(BltFx);
2563 U5(BltFx).dwFillColor = 0xaabbccdd;
2565 hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2566 ok(hr == DD_OK, "IDirectDrawSurface_Blt with a valid rectangle for color fill returned %08x\n", hr);
2567 hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, &invalid3, DDBLT_COLORFILL, &BltFx);
2568 ok(hr == DD_OK, "IDirectDrawSurface_Blt with a invalid, unused rectangle returned %08x\n", hr);
2569 hr = IDirectDrawSurface_Blt(surface2, &invalid1, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2570 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2571 hr = IDirectDrawSurface_Blt(surface2, &invalid2, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2572 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2573 hr = IDirectDrawSurface_Blt(surface2, &invalid3, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2574 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2575 hr = IDirectDrawSurface_Blt(surface2, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2576 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2578 /* Valid on surface 1 */
2579 hr = IDirectDrawSurface_Blt(surface1, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2580 ok(hr == DD_OK, "IDirectDrawSurface_Blt with a subrectangle fill returned %08x\n", hr);
2582 /* Works - stretched blit */
2583 hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, NULL, 0, NULL);
2584 ok(hr == DD_OK, "IDirectDrawSurface_Blt from a smaller to a bigger surface returned %08x\n", hr);
2585 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, NULL, 0, NULL);
2586 ok(hr == DD_OK, "IDirectDrawSurface_Blt from a bigger to a smaller surface %08x\n", hr);
2588 /* Invalid dest rects in sourced blits */
2589 hr = IDirectDrawSurface_Blt(surface2, &invalid1, surface1, NULL, 0, NULL);
2590 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2591 hr = IDirectDrawSurface_Blt(surface2, &invalid2, surface1, NULL, 0, NULL);
2592 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2593 hr = IDirectDrawSurface_Blt(surface2, &invalid3, surface1, NULL, 0, NULL);
2594 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2595 hr = IDirectDrawSurface_Blt(surface2, &invalid4, surface1, NULL, 0, NULL);
2596 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2598 /* Invalid src rects */
2599 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid1, 0, NULL);
2600 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2601 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid2, 0, NULL);
2602 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2603 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid3, 0, NULL);
2604 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2605 hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, &invalid4, 0, NULL);
2606 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2608 IDirectDrawSurface_Release(surface1);
2609 IDirectDrawSurface_Release(surface2);
2612 static void PaletteTest(void)
2615 LPDIRECTDRAWSURFACE lpSurf = NULL;
2617 IDirectDrawPalette *palette = NULL;
2618 PALETTEENTRY Table[256];
2619 PALETTEENTRY palEntries[256];
2622 for(i=0; i<256; i++)
2624 Table[i].peRed = 0xff;
2625 Table[i].peGreen = 0;
2626 Table[i].peBlue = 0;
2627 Table[i].peFlags = 0;
2630 /* Create a 8bit palette without DDPCAPS_ALLOW256 set */
2631 hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_8BIT, Table, &palette, NULL);
2632 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2633 if (FAILED(hr)) goto err;
2634 /* Read back the palette and verify the entries. Without DDPCAPS_ALLOW256 set
2635 / entry 0 and 255 should have been overwritten with black and white */
2636 IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2637 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2640 ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2641 "Palette entry 0 of a palette without DDPCAPS_ALLOW256 set should be (0,0,0) but it is (%d,%d,%d)\n",
2642 palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2643 ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2644 "Palette entry 255 of a palette without DDPCAPS_ALLOW256 set should be (255,255,255) but it is (%d,%d,%d)\n",
2645 palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2647 /* Entry 1-254 should contain red */
2648 for(i=1; i<255; i++)
2649 ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2650 "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2651 i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2654 /* CreatePalette without DDPCAPS_ALLOW256 ignores entry 0 and 255,
2655 / now check we are able to update the entries afterwards. */
2656 IDirectDrawPalette_SetEntries(palette , 0, 0, 256, &Table[0]);
2657 ok(hr == DD_OK, "SetEntries failed with %08x\n", hr);
2658 IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2659 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2662 ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2663 "Palette entry 0 should have been set to (0,0,0) but it contains (%d,%d,%d)\n",
2664 palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2665 ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2666 "Palette entry 255 should have been set to (255,255,255) but it contains (%d,%d,%d)\n",
2667 palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2669 IDirectDrawPalette_Release(palette);
2671 /* Create a 8bit palette with DDPCAPS_ALLOW256 set */
2672 hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
2673 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2674 if (FAILED(hr)) goto err;
2676 IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2677 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2680 /* All entries should contain red */
2681 for(i=0; i<256; i++)
2682 ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2683 "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2684 i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2687 /* Try to set palette to a non-palettized surface */
2688 ddsd.dwSize = sizeof(ddsd);
2689 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2690 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2691 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2693 ddsd.dwHeight = 600;
2694 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2695 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
2696 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
2697 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
2698 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
2699 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurf, NULL);
2700 ok(hr==DD_OK, "CreateSurface returned: %x\n",hr);
2702 skip("failed to create surface\n");
2706 hr = IDirectDrawSurface_SetPalette(lpSurf, palette);
2707 ok(hr == DDERR_INVALIDPIXELFORMAT, "CreateSurface returned: %x\n",hr);
2709 IDirectDrawPalette_Release(palette);
2712 hr = IDirectDrawSurface_GetPalette(lpSurf, &palette);
2713 ok(hr == DDERR_NOPALETTEATTACHED, "CreateSurface returned: %x\n",hr);
2717 if (lpSurf) IDirectDrawSurface_Release(lpSurf);
2718 if (palette) IDirectDrawPalette_Release(palette);
2721 static void StructSizeTest(void)
2723 IDirectDrawSurface *surface1;
2724 IDirectDrawSurface7 *surface7;
2726 DDSURFACEDESC desc1;
2727 DDSURFACEDESC2 desc2;
2728 char blob[1024]; /* To get a bunch of writable memory */
2730 DDSURFACEDESC create;
2733 memset(&desc, 0, sizeof(desc));
2734 memset(&create, 0, sizeof(create));
2736 memset(&create, 0, sizeof(create));
2737 create.dwSize = sizeof(create);
2738 create.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2739 create.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2740 create.dwHeight = 128;
2741 create.dwWidth = 128;
2742 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2743 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2744 hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface7, (void **) &surface7);
2745 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2747 desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2748 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2749 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2750 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2751 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2753 desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2754 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2755 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2756 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2757 ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2759 desc.desc2.dwSize = 0;
2760 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2761 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2762 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2763 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2765 desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2766 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2767 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2768 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2769 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2771 desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2772 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2773 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2774 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2775 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2777 /* Tests for Lock() */
2779 desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2780 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2781 ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2782 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2783 ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2784 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2785 ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2786 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2787 ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2789 desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2790 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2791 ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2792 ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2793 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2794 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2795 ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2796 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2797 ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2799 desc.desc2.dwSize = 0;
2800 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2801 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size 0 returned %08x\n", hr);
2802 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2803 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2804 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size 0 returned %08x\n", hr);
2805 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2807 desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2808 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2809 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2810 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2811 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2812 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2813 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2815 desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2816 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2817 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2818 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2819 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2820 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2821 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2823 IDirectDrawSurface7_Release(surface7);
2824 IDirectDrawSurface_Release(surface1);
2827 static void SurfaceCapsTest(void)
2829 DDSURFACEDESC create;
2832 IDirectDrawSurface *surface1 = NULL;
2833 DDSURFACEDESC2 create2, desc2;
2834 IDirectDrawSurface7 *surface7 = NULL;
2835 IDirectDraw7 *dd7 = NULL;
2836 DWORD create_caps[] = {
2837 DDSCAPS_OFFSCREENPLAIN,
2839 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD,
2841 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2842 DDSCAPS_PRIMARYSURFACE,
2843 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY
2845 DWORD expected_caps[] = {
2846 DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2847 DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2848 DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD,
2849 DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2850 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2851 DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_VISIBLE,
2852 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_VISIBLE
2856 /* Tests various surface flags, what changes do they undergo during surface creation. Forsaken
2857 * engine expects texture surfaces without memory flag to get a video memory flag right after
2858 * creation. Currently, Wine adds DDSCAPS_FRONTBUFFER to primary surface, but native doesn't do this
2859 * for single buffered primaries. Because of this primary surface creation tests are todo_wine. No real
2860 * app is known so far to care about this. */
2862 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
2864 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
2868 for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2870 memset(&create, 0, sizeof(create));
2871 create.dwSize = sizeof(create);
2872 create.ddsCaps.dwCaps = create_caps[i];
2873 create.dwFlags = DDSD_CAPS;
2875 if (!(create.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2877 create.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2878 create.dwHeight = 128;
2879 create.dwWidth = 128;
2882 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2883 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2887 memset(&desc, 0, sizeof(desc));
2888 desc.dwSize = sizeof(DDSURFACEDESC);
2889 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc);
2890 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2892 if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
2893 ok(desc.ddsCaps.dwCaps == expected_caps[i],
2894 "GetSurfaceDesc returned caps %x, expected %x\n", desc.ddsCaps.dwCaps,
2897 todo_wine ok(desc.ddsCaps.dwCaps == expected_caps[i],
2898 "GetSurfaceDesc returned caps %x, expected %x\n", desc.ddsCaps.dwCaps,
2901 IDirectDrawSurface_Release(surface1);
2905 /* Test for differences in ddraw 7 */
2906 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2907 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
2910 skip("Failed to get IDirectDraw7 interface, skipping tests\n");
2914 for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2916 memset(&create2, 0, sizeof(create2));
2917 create2.dwSize = sizeof(create2);
2918 create2.ddsCaps.dwCaps = create_caps[i];
2919 create2.dwFlags = DDSD_CAPS;
2921 if (!(create2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2923 create2.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2924 create2.dwHeight = 128;
2925 create2.dwWidth = 128;
2928 hr = IDirectDraw7_CreateSurface(dd7, &create2, &surface7, NULL);
2929 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2933 memset(&desc2, 0, sizeof(desc2));
2934 desc2.dwSize = sizeof(DDSURFACEDESC2);
2935 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc2);
2936 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2938 if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
2939 ok(desc2.ddsCaps.dwCaps == expected_caps[i],
2940 "GetSurfaceDesc returned caps %x, expected %x\n", desc2.ddsCaps.dwCaps,
2943 todo_wine ok(desc2.ddsCaps.dwCaps == expected_caps[i],
2944 "GetSurfaceDesc returned caps %x, expected %x\n", desc2.ddsCaps.dwCaps,
2947 IDirectDrawSurface7_Release(surface7);
2951 IDirectDraw7_Release(dd7);
2954 memset(&create, 0, sizeof(create));
2955 create.dwSize = sizeof(create);
2956 create.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2957 create.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY;
2958 create.dwWidth = 64;
2959 create.dwHeight = 64;
2960 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2961 ok(hr == DDERR_INVALIDCAPS, "Creating a SYSMEM | VIDMEM surface returned 0x%08x, expected DDERR_INVALIDCAPS\n", hr);
2962 if(surface1) IDirectDrawSurface_Release(surface1);
2965 static BOOL can_create_primary_surface(void)
2968 IDirectDrawSurface *surface;
2971 memset(&ddsd, 0, sizeof(ddsd));
2972 ddsd.dwSize = sizeof(ddsd);
2973 ddsd.dwFlags = DDSD_CAPS;
2974 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2975 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2976 if(FAILED(hr)) return FALSE;
2977 IDirectDrawSurface_Release(surface);
2981 static void dctest_surf(IDirectDrawSurface *surf, int ddsdver) {
2983 HDC dc, dc2 = (HDC) 0x1234;
2985 DDSURFACEDESC2 ddsd2;
2987 memset(&ddsd, 0, sizeof(ddsd));
2988 ddsd.dwSize = sizeof(ddsd);
2989 memset(&ddsd2, 0, sizeof(ddsd2));
2990 ddsd2.dwSize = sizeof(ddsd2);
2992 hr = IDirectDrawSurface_GetDC(surf, &dc);
2993 ok(hr == DD_OK, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
2995 hr = IDirectDrawSurface_GetDC(surf, &dc2);
2996 ok(hr == DDERR_DCALREADYCREATED, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
2997 ok(dc2 == (HDC) 0x1234, "The failed GetDC call changed the dc: %p\n", dc2);
2999 hr = IDirectDrawSurface_Lock(surf, NULL, ddsdver == 1 ? &ddsd : ((DDSURFACEDESC *) &ddsd2), 0, NULL);
3000 ok(hr == DDERR_SURFACEBUSY, "IDirectDrawSurface_Lock returned 0x%08x, expected DDERR_ALREADYLOCKED\n", hr);
3002 hr = IDirectDrawSurface_ReleaseDC(surf, dc);
3003 ok(hr == DD_OK, "IDirectDrawSurface_ReleaseDC failed: 0x%08x\n", hr);
3004 hr = IDirectDrawSurface_ReleaseDC(surf, dc);
3005 ok(hr == DDERR_NODC, "IDirectDrawSurface_ReleaseDC returned 0x%08x, expected DDERR_NODC\n", hr);
3008 static void GetDCTest(void)
3011 DDSURFACEDESC2 ddsd2;
3012 IDirectDrawSurface *surf;
3013 IDirectDrawSurface2 *surf2;
3014 IDirectDrawSurface4 *surf4;
3015 IDirectDrawSurface7 *surf7;
3016 IDirectDrawSurface *tmp;
3017 IDirectDrawSurface7 *tmp7;
3024 memset(&ddsd, 0, sizeof(ddsd));
3025 ddsd.dwSize = sizeof(ddsd);
3026 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3029 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3030 memset(&ddsd2, 0, sizeof(ddsd2));
3031 ddsd2.dwSize = sizeof(ddsd2);
3032 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3034 ddsd2.dwHeight = 64;
3035 ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3037 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
3038 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3039 dctest_surf(surf, 1);
3040 IDirectDrawSurface_Release(surf);
3042 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3043 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3045 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3046 ok(hr == DD_OK, "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
3047 dctest_surf(surf, 1);
3049 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
3050 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr);
3051 dctest_surf((IDirectDrawSurface *) surf2, 1);
3053 IDirectDrawSurface2_Release(surf2);
3054 IDirectDrawSurface_Release(surf);
3055 IDirectDraw2_Release(dd2);
3057 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3058 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3061 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3062 ok(hr == DD_OK, "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
3063 dctest_surf((IDirectDrawSurface *) surf4, 2);
3065 hr = IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)&surf);
3066 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3068 hr = IDirectDrawSurface4_GetDC(surf4, &dc);
3069 ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
3071 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, NULL);
3072 ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
3074 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
3075 ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
3076 ok(tmp == surf, "Expected surface %p, got %p.\n\n", surf, tmp);
3078 hr = IDirectDrawSurface4_ReleaseDC(surf4, dc);
3079 ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
3081 dc = CreateCompatibleDC(NULL);
3082 ok(!!dc, "CreateCompatibleDC failed.\n");
3084 tmp = (IDirectDrawSurface *)0xdeadbeef;
3085 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
3086 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3087 ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
3089 ok(DeleteDC(dc), "DeleteDC failed.\n");
3091 tmp = (IDirectDrawSurface *)0xdeadbeef;
3092 hr = IDirectDraw4_GetSurfaceFromDC(dd4, NULL, (IDirectDrawSurface4 **)&tmp);
3093 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3094 ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
3096 IDirectDrawSurface4_Release(surf4);
3097 IDirectDraw4_Release(dd4);
3099 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3100 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3102 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3103 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
3104 dctest_surf((IDirectDrawSurface *) surf7, 2);
3106 hr = IDirectDrawSurface7_GetDC(surf7, &dc);
3107 ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
3109 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, NULL);
3110 ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
3112 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
3113 ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
3114 ok(tmp7 == surf7, "Expected surface %p, got %p.\n\n", surf7, tmp7);
3115 IDirectDrawSurface7_Release(tmp7);
3117 hr = IDirectDrawSurface7_ReleaseDC(surf7, dc);
3118 ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
3120 dc = CreateCompatibleDC(NULL);
3121 ok(!!dc, "CreateCompatibleDC failed.\n");
3123 tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
3124 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
3125 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3126 ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
3128 ok(DeleteDC(dc), "DeleteDC failed.\n");
3130 tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
3131 hr = IDirectDraw7_GetSurfaceFromDC(dd7, NULL, (IDirectDrawSurface7 **)&tmp7);
3132 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3133 ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
3135 IDirectDrawSurface7_Release(surf7);
3136 IDirectDraw7_Release(dd7);
3139 static void GetDCFormatTest(void)
3141 DDSURFACEDESC2 ddsd;
3143 IDirectDrawSurface7 *surface;
3158 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3159 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
3166 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3167 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
3174 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3175 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
3178 DDERR_CANTCREATEDC /* Vista+ */
3183 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3184 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}
3187 DDERR_CANTCREATEDC /* Vista+ */
3192 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3193 {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}
3196 DDERR_CANTCREATEDC /* Vista+ */
3201 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3202 {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}
3205 DDERR_CANTCREATEDC /* Vista+ */
3210 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3211 {16}, {0x0000F800}, {0x000007E0}, {0x0000001F}, {0x00000000}
3218 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3219 {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00008000}
3226 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3227 {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00000000}
3234 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3235 { 8}, {0x000000E0}, {0x0000001C}, {0x00000003}, {0x00000000}
3240 /* Untested, windows test machine didn't support this format */
3241 "D3DFMT_A2R10G10B10",
3243 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3244 {32}, {0xC0000000}, {0x3FF00000}, {0x000FFC00}, {0x000003FF}
3249 * GetDC on a P8 surface fails unless the display mode is 8 bpp. This is not
3250 * implemented in wine yet, so disable the test for now. Succeeding P8 getDC
3251 * calls are tested in the ddraw.visual test.
3256 sizeof(DDPIXELFORMAT), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0,
3257 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3265 sizeof(DDPIXELFORMAT), DDPF_LUMINANCE, 0,
3266 {8 }, {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}
3273 sizeof(DDPIXELFORMAT), DDPF_ALPHAPIXELS | DDPF_LUMINANCE, 0,
3274 {16}, {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}
3281 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','1'),
3282 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3289 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','2'),
3290 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3297 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','3'),
3298 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3305 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','4'),
3306 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3313 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','5'),
3314 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3320 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3321 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed, hr = 0x%08x\n", hr);
3323 for(i = 0; i < (sizeof(testdata) / sizeof(testdata[0])); i++)
3325 memset(&ddsd, 0, sizeof(ddsd));
3326 ddsd.dwSize = sizeof(ddsd);
3327 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3330 U4(ddsd).ddpfPixelFormat = testdata[i].fmt;
3331 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3333 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3336 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
3337 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
3338 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3341 skip("IDirectDraw7_CreateSurface failed, hr = 0x%08x, format %s\n", hr, testdata[i].name);
3346 dc = (void *) 0x1234;
3347 hr = IDirectDrawSurface7_GetDC(surface, &dc);
3348 if(testdata[i].getdc_capable)
3351 (testdata[i].alt_result && hr == testdata[i].alt_result),
3352 "GetDC on a %s surface failed(0x%08x), expected it to work\n",
3353 testdata[i].name, hr);
3357 ok(FAILED(hr), "GetDC on a %s surface succeeded(0x%08x), expected it to fail\n",
3358 testdata[i].name, hr);
3363 IDirectDrawSurface7_ReleaseDC(surface, dc);
3364 ok(hr == DD_OK, "IDirectDrawSurface7_ReleaseDC failed, hr = 0x%08x\n", hr);
3369 ok(dc == NULL, "After failed GetDC dc is %p\n", dc);
3372 IDirectDrawSurface7_Release(surface);
3375 IDirectDraw7_Release(dd7);
3378 static void BackBufferCreateSurfaceTest(void)
3381 DDSURFACEDESC created_ddsd;
3382 DDSURFACEDESC2 ddsd2;
3383 IDirectDrawSurface *surf;
3384 IDirectDrawSurface4 *surf4;
3385 IDirectDrawSurface7 *surf7;
3391 const DWORD caps = DDSCAPS_BACKBUFFER;
3392 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3394 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3396 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3400 memset(&ddsd, 0, sizeof(ddsd));
3401 ddsd.dwSize = sizeof(ddsd);
3402 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3405 ddsd.ddsCaps.dwCaps = caps;
3406 memset(&ddsd2, 0, sizeof(ddsd2));
3407 ddsd2.dwSize = sizeof(ddsd2);
3408 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3410 ddsd2.dwHeight = 64;
3411 ddsd2.ddsCaps.dwCaps = caps;
3412 memset(&created_ddsd, 0, sizeof(created_ddsd));
3413 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3415 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
3416 todo_wine ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3419 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3420 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3421 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3422 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3424 IDirectDrawSurface_Release(surf);
3427 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3428 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3430 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3431 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3432 DDERR_INVALIDCAPS, hr);
3434 IDirectDraw2_Release(dd2);
3436 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3437 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3439 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3440 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3441 DDERR_INVALIDCAPS, hr);
3443 IDirectDraw4_Release(dd4);
3445 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3446 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3448 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3449 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3450 DDERR_INVALIDCAPS, hr);
3452 IDirectDraw7_Release(dd7);
3455 static void BackBufferAttachmentFlipTest(void)
3458 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3460 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3462 hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3463 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3465 /* Perform attachment tests on a back-buffer */
3466 memset(&ddsd, 0, sizeof(ddsd));
3467 ddsd.dwSize = sizeof(ddsd);
3468 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3469 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3470 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3471 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3472 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
3473 todo_wine ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3475 if (surface2 != NULL)
3477 /* Try a single primary and a two back buffers */
3478 memset(&ddsd, 0, sizeof(ddsd));
3479 ddsd.dwSize = sizeof(ddsd);
3480 ddsd.dwFlags = DDSD_CAPS;
3481 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3482 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
3483 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3485 memset(&ddsd, 0, sizeof(ddsd));
3486 ddsd.dwSize = sizeof(ddsd);
3487 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3488 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3489 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3490 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3491 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
3492 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3494 /* This one has a different size */
3495 memset(&ddsd, 0, sizeof(ddsd));
3496 ddsd.dwSize = sizeof(ddsd);
3497 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3498 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3500 ddsd.dwHeight = 128;
3501 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
3502 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3504 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3505 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3506 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3509 /* Try flipping the surfaces */
3510 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3511 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3512 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3513 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3515 /* Try the reverse without detaching first */
3516 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3517 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3518 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3519 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3521 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3522 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3523 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3526 /* Try flipping the surfaces */
3527 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3528 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3529 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3530 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3532 /* Try to detach reversed */
3533 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3534 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3535 /* Now the proper detach */
3536 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3537 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3539 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3540 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3541 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3544 /* Try flipping the surfaces */
3545 hr = IDirectDrawSurface_Flip(surface3, NULL, DDFLIP_WAIT);
3546 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3547 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3548 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3549 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3550 ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3552 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3553 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3555 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3556 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3557 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3558 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3560 IDirectDrawSurface_Release(surface4);
3561 IDirectDrawSurface_Release(surface3);
3562 IDirectDrawSurface_Release(surface2);
3563 IDirectDrawSurface_Release(surface1);
3566 hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
3567 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3569 DestroyWindow(window);
3572 START_TEST(dsurface)
3577 if (!CreateDirectDraw())
3580 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3581 if (ret == E_NOINTERFACE)
3583 win_skip("DirectDraw4 and higher are not supported\n");
3584 ReleaseDirectDraw();
3587 IDirectDraw_Release(dd4);
3589 if(!can_create_primary_surface())
3591 skip("Unable to create primary surface\n");
3595 ddcaps.dwSize = sizeof(DDCAPS);
3596 ret = IDirectDraw_GetCaps(lpDD, &ddcaps, NULL);
3599 skip("IDirectDraw_GetCaps failed with %08x\n", ret);
3603 MipMapCreationTest();
3604 SrcColorKey32BlitTest();
3615 test_lockrect_invalid();
3625 BackBufferCreateSurfaceTest();
3626 BackBufferAttachmentFlipTest();
3627 ReleaseDirectDraw();