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"
28 #include "wine/exception.h"
33 static LPDIRECTDRAW lpDD = NULL;
36 static BOOL CreateDirectDraw(void)
40 rc = DirectDrawCreate(NULL, &lpDD, NULL);
41 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
43 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
47 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
48 ok(rc==DD_OK,"SetCooperativeLevel returned: %x\n",rc);
54 static void ReleaseDirectDraw(void)
58 IDirectDraw_Release(lpDD);
63 static void MipMapCreationTest(void)
65 LPDIRECTDRAWSURFACE lpDDSMipMapTest;
69 /* First mipmap creation test: create a surface with DDSCAPS_COMPLEX,
70 DDSCAPS_MIPMAP, and DDSD_MIPMAPCOUNT. This create the number of
71 requested mipmap levels. */
72 ddsd.dwSize = sizeof(ddsd);
73 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
74 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
75 U2(ddsd).dwMipMapCount = 3;
78 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
79 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
82 skip("failed to create surface\n");
86 /* Check the number of created mipmaps */
87 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
88 ddsd.dwSize = sizeof(ddsd);
89 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
90 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
91 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
92 "GetSurfaceDesc returned no mipmapcount.\n");
93 ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %d.\n",
94 U2(ddsd).dwMipMapCount);
96 /* Destroy the surface. */
97 IDirectDrawSurface_Release(lpDDSMipMapTest);
100 /* Second mipmap creation test: create a surface without a mipmap
101 count, with DDSCAPS_MIPMAP and without DDSCAPS_COMPLEX.
102 This creates a single mipmap level. */
103 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
104 ddsd.dwSize = sizeof(ddsd);
105 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
106 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
109 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
110 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
113 skip("failed to create surface\n");
116 /* Check the number of created mipmaps */
117 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
118 ddsd.dwSize = sizeof(ddsd);
119 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
120 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
121 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
122 "GetSurfaceDesc returned no mipmapcount.\n");
123 ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %d.\n",
124 U2(ddsd).dwMipMapCount);
126 /* Destroy the surface. */
127 IDirectDrawSurface_Release(lpDDSMipMapTest);
130 /* Third mipmap creation test: create a surface with DDSCAPS_MIPMAP,
131 DDSCAPS_COMPLEX and without DDSD_MIPMAPCOUNT.
132 It's an undocumented features where a chain of mipmaps, starting from
133 he specified size and down to the smallest size, is automatically
135 Anarchy Online needs this feature to work. */
136 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
137 ddsd.dwSize = sizeof(ddsd);
138 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
139 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
142 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
143 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
146 skip("failed to create surface\n");
150 /* Check the number of created mipmaps */
151 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
152 ddsd.dwSize = sizeof(ddsd);
153 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
154 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
155 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
156 "GetSurfaceDesc returned no mipmapcount.\n");
157 ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
158 U2(ddsd).dwMipMapCount);
160 /* Destroy the surface. */
161 IDirectDrawSurface_Release(lpDDSMipMapTest);
164 /* Fourth mipmap creation test: same as above with a different texture
166 The purpose is to verify that the number of generated mipmaps is
167 dependent on the smallest dimension. */
168 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
169 ddsd.dwSize = sizeof(ddsd);
170 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
171 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
174 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
175 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
178 skip("failed to create surface\n");
182 /* Check the number of created mipmaps */
183 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
184 ddsd.dwSize = sizeof(ddsd);
185 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
186 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
187 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
188 "GetSurfaceDesc returned no mipmapcount.\n");
189 ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
190 U2(ddsd).dwMipMapCount);
192 /* Destroy the surface. */
193 IDirectDrawSurface_Release(lpDDSMipMapTest);
196 /* Fifth mipmap creation test: try to create a surface with
197 DDSCAPS_COMPLEX, DDSCAPS_MIPMAP, DDSD_MIPMAPCOUNT,
198 where dwMipMapCount = 0. This should fail. */
200 ddsd.dwSize = sizeof(ddsd);
201 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
202 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
203 U2(ddsd).dwMipMapCount = 0;
206 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
207 ok(rc==DDERR_INVALIDPARAMS,"CreateSurface returned: %x\n",rc);
209 /* Destroy the surface. */
211 IDirectDrawSurface_Release(lpDDSMipMapTest);
215 static void SrcColorKey32BlitTest(void)
217 LPDIRECTDRAWSURFACE lpSrc;
218 LPDIRECTDRAWSURFACE lpDst;
219 DDSURFACEDESC ddsd, ddsd2, ddsd3;
220 DDCOLORKEY DDColorKey;
225 ddsd2.dwSize = sizeof(ddsd2);
226 ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
228 ddsd.dwSize = sizeof(ddsd);
229 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
230 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
231 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
234 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
235 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
236 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
237 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
238 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
239 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
240 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
243 skip("failed to create surface\n");
247 ddsd.dwFlags |= DDSD_CKSRCBLT;
248 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
249 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
250 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
251 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
254 skip("failed to create surface\n");
258 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
259 ok(rc==DD_OK,"Lock returned: %x\n",rc);
260 lpData = ddsd2.lpSurface;
261 lpData[0] = 0xCCCCCCCC;
262 lpData[1] = 0xCCCCCCCC;
263 lpData[2] = 0xCCCCCCCC;
264 lpData[3] = 0xCCCCCCCC;
266 memset(&ddsd3, 0, sizeof(ddsd3));
267 ddsd3.dwSize = sizeof(ddsd3);
268 ddsd3.ddpfPixelFormat.dwSize = sizeof(ddsd3.ddpfPixelFormat);
269 rc = IDirectDrawSurface_GetSurfaceDesc(lpDst, &ddsd3);
270 ok(rc == DD_OK, "IDirectDrawSurface_GetSurfaceDesc between a lock/unlock pair returned %08x\n", rc);
271 ok(ddsd3.lpSurface == ddsd3.lpSurface, "lpSurface from GetSurfaceDesc(%p) differs from the one returned by Lock(%p)\n", ddsd3.lpSurface, ddsd2.lpSurface);
273 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
274 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
276 memset(&ddsd3, 0, sizeof(ddsd3));
277 ddsd3.dwSize = sizeof(ddsd3);
278 ddsd3.ddpfPixelFormat.dwSize = sizeof(ddsd3.ddpfPixelFormat);
279 rc = IDirectDrawSurface_GetSurfaceDesc(lpDst, &ddsd3);
280 ok(rc == DD_OK, "IDirectDrawSurface_GetSurfaceDesc between a lock/unlock pair returned %08x\n", rc);
281 ok(ddsd3.lpSurface == NULL, "lpSurface from GetSurfaceDesc(%p) is not NULL after unlock\n", ddsd3.lpSurface);
283 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
284 ok(rc==DD_OK,"Lock returned: %x\n",rc);
285 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
286 lpData = ddsd2.lpSurface;
287 lpData[0] = 0x77010203;
288 lpData[1] = 0x00010203;
289 lpData[2] = 0x77FF00FF;
290 lpData[3] = 0x00FF00FF;
291 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
292 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
294 IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
296 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
297 ok(rc==DD_OK,"Lock returned: %x\n",rc);
298 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
299 lpData = ddsd2.lpSurface;
300 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
301 * color keying, but copy it to the destination surface. Others apply it for color keying, but
302 * do not copy it into the destination surface.
304 if(lpData[0]==0x00010203) {
305 trace("X channel was not copied into the destination surface\n");
306 ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
307 "Destination data after blitting is not correct\n");
309 ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
310 "Destination data after blitting is not correct\n");
312 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
313 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
315 /* Below we repeat the same test as above but now using BltFast instead of Blt. Before
316 * we can carry out the test we need to restore the color of the destination surface.
318 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
319 ok(rc==DD_OK,"Lock returned: %x\n",rc);
320 lpData = ddsd2.lpSurface;
321 lpData[0] = 0xCCCCCCCC;
322 lpData[1] = 0xCCCCCCCC;
323 lpData[2] = 0xCCCCCCCC;
324 lpData[3] = 0xCCCCCCCC;
325 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
326 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
328 IDirectDrawSurface_BltFast(lpDst, 0, 0, lpSrc, NULL, DDBLTFAST_SRCCOLORKEY);
330 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
331 ok(rc==DD_OK,"Lock returned: %x\n",rc);
332 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
333 lpData = ddsd2.lpSurface;
334 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
335 * color keying, but copy it to the destination surface. Others apply it for color keying, but
336 * do not copy it into the destination surface.
338 if(lpData[0]==0x00010203) {
339 trace("X channel was not copied into the destination surface\n");
340 ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
341 "Destination data after blitting is not correct\n");
343 ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
344 "Destination data after blitting is not correct\n");
346 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
347 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
349 /* Also test SetColorKey */
350 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
351 ok(DDColorKey.dwColorSpaceLowValue == 0xFF00FF && DDColorKey.dwColorSpaceHighValue == 0xFF00FF,
352 "GetColorKey does not return the colorkey used at surface creation\n");
354 DDColorKey.dwColorSpaceLowValue = 0x00FF00;
355 DDColorKey.dwColorSpaceHighValue = 0x00FF00;
356 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
358 DDColorKey.dwColorSpaceLowValue = 0;
359 DDColorKey.dwColorSpaceHighValue = 0;
360 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
361 ok(DDColorKey.dwColorSpaceLowValue == 0x00FF00 && DDColorKey.dwColorSpaceHighValue == 0x00FF00,
362 "GetColorKey does not return the colorkey set with SetColorKey\n");
364 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
365 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
366 IDirectDrawSurface_GetSurfaceDesc(lpSrc, &ddsd);
367 ok(ddsd.ddckCKSrcBlt.dwColorSpaceLowValue == 0x00FF00 && ddsd.ddckCKSrcBlt.dwColorSpaceHighValue == 0x00FF00,
368 "GetSurfaceDesc does not return the colorkey set with SetColorKey\n");
370 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
371 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
372 DDColorKey.dwColorSpaceHighValue = 0x000000;
373 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
375 DDColorKey.dwColorSpaceLowValue = 0;
376 DDColorKey.dwColorSpaceHighValue = 0;
377 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
378 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
379 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
381 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
382 DDColorKey.dwColorSpaceHighValue = 0x000001;
383 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
385 DDColorKey.dwColorSpaceLowValue = 0;
386 DDColorKey.dwColorSpaceHighValue = 0;
387 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
388 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
389 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
391 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
392 DDColorKey.dwColorSpaceHighValue = 0x0000FE;
393 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
395 DDColorKey.dwColorSpaceLowValue = 0;
396 DDColorKey.dwColorSpaceHighValue = 0;
397 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
398 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
399 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
401 IDirectDrawSurface_Release(lpSrc);
402 IDirectDrawSurface_Release(lpDst);
404 /* start with a new set of surfaces to test the color keying parameters to blit */
405 memset(&ddsd, 0, sizeof(ddsd));
406 ddsd.dwSize = sizeof(ddsd);
407 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
408 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
409 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
412 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
413 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
414 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
415 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
416 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
417 ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0xFF0000;
418 ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0xFF0000;
419 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x00FF00;
420 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x00FF00;
421 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
422 ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
425 skip("Failed to create surface\n");
429 /* start with a new set of surfaces to test the color keying parameters to blit */
430 memset(&ddsd, 0, sizeof(ddsd));
431 ddsd.dwSize = sizeof(ddsd);
432 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
433 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
434 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
437 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
438 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
439 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
440 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
441 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
442 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x0000FF;
443 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x0000FF;
444 ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0x000000;
445 ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0x000000;
446 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
447 ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
450 skip("Failed to create surface\n");
451 IDirectDrawSurface_Release(lpDst);
455 memset(&fx, 0, sizeof(fx));
456 fx.dwSize = sizeof(fx);
457 fx.ddckSrcColorkey.dwColorSpaceHighValue = 0x110000;
458 fx.ddckSrcColorkey.dwColorSpaceLowValue = 0x110000;
459 fx.ddckDestColorkey.dwColorSpaceHighValue = 0x001100;
460 fx.ddckDestColorkey.dwColorSpaceLowValue = 0x001100;
462 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
463 ok(rc==DD_OK,"Lock returned: %x\n",rc);
464 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
465 lpData = ddsd2.lpSurface;
466 lpData[0] = 0x000000FF; /* Applies to src blt key in src surface */
467 lpData[1] = 0x00000000; /* Applies to dst blt key in src surface */
468 lpData[2] = 0x00FF0000; /* Dst color key in dst surface */
469 lpData[3] = 0x0000FF00; /* Src color key in dst surface */
470 lpData[4] = 0x00001100; /* Src color key in ddbltfx */
471 lpData[5] = 0x00110000; /* Dst color key in ddbltfx */
472 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
473 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
475 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
476 ok(rc==DD_OK,"Lock returned: %x\n",rc);
477 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
478 lpData = ddsd2.lpSurface;
479 lpData[0] = 0x55555555;
480 lpData[1] = 0x55555555;
481 lpData[2] = 0x55555555;
482 lpData[3] = 0x55555555;
483 lpData[4] = 0x55555555;
484 lpData[5] = 0x55555555;
485 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
486 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
488 /* Test a blit without keying */
489 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, 0, &fx);
490 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
492 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
493 ok(rc==DD_OK,"Lock returned: %x\n",rc);
494 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
495 lpData = ddsd2.lpSurface;
496 /* Should have copied src data unmodified to dst */
497 ok(lpData[0] == 0x000000FF &&
498 lpData[1] == 0x00000000 &&
499 lpData[2] == 0x00FF0000 &&
500 lpData[3] == 0x0000FF00 &&
501 lpData[4] == 0x00001100 &&
502 lpData[5] == 0x00110000, "Surface data after unkeyed blit does not match\n");
504 lpData[0] = 0x55555555;
505 lpData[1] = 0x55555555;
506 lpData[2] = 0x55555555;
507 lpData[3] = 0x55555555;
508 lpData[4] = 0x55555555;
509 lpData[5] = 0x55555555;
510 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
511 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
514 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
515 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
517 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
518 ok(rc==DD_OK,"Lock returned: %x\n",rc);
519 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
520 lpData = ddsd2.lpSurface;
522 ok(lpData[0] == 0x55555555 && /* Here the src key applied */
523 lpData[1] == 0x00000000 &&
524 lpData[2] == 0x00FF0000 &&
525 lpData[3] == 0x0000FF00 &&
526 lpData[4] == 0x00001100 &&
527 lpData[5] == 0x00110000, "Surface data after srckey blit does not match\n");
529 lpData[0] = 0x55555555;
530 lpData[1] = 0x55555555;
531 lpData[2] = 0x55555555;
532 lpData[3] = 0x55555555;
533 lpData[4] = 0x55555555;
534 lpData[5] = 0x55555555;
535 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
536 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
539 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
540 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
542 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
543 ok(rc==DD_OK,"Lock returned: %x\n",rc);
544 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
545 lpData = ddsd2.lpSurface;
547 ok(lpData[0] == 0x000000FF &&
548 lpData[1] == 0x00000000 &&
549 lpData[2] == 0x00FF0000 &&
550 lpData[3] == 0x0000FF00 &&
551 lpData[4] == 0x00001100 &&
552 lpData[5] == 0x55555555, /* Override key applies here */
553 "Surface data after src override key blit does not match\n");
555 lpData[0] = 0x55555555;
556 lpData[1] = 0x55555555;
557 lpData[2] = 0x55555555;
558 lpData[3] = 0x55555555;
559 lpData[4] = 0x55555555;
560 lpData[5] = 0x55555555;
561 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
562 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
564 /* Src override AND src key. That is not supposed to work */
565 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &fx);
566 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
568 /* Verify that the destination is unchanged */
569 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
570 ok(rc==DD_OK,"Lock returned: %x\n",rc);
571 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
572 lpData = ddsd2.lpSurface;
574 ok(lpData[0] == 0x55555555 &&
575 lpData[1] == 0x55555555 &&
576 lpData[2] == 0x55555555 &&
577 lpData[3] == 0x55555555 &&
578 lpData[4] == 0x55555555 &&
579 lpData[5] == 0x55555555, /* Override key applies here */
580 "Surface data after src key blit with override does not match\n");
582 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
583 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
584 lpData[2] = 0x00001100; /* Dest key in override */
585 lpData[3] = 0x00001100; /* Dest key in override */
586 lpData[4] = 0x00000000; /* Dest key in src surface */
587 lpData[5] = 0x00000000; /* Dest key in src surface */
588 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
589 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
592 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
593 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
595 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
596 ok(rc==DD_OK,"Lock returned: %x\n",rc);
597 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
598 lpData = ddsd2.lpSurface;
600 /* DirectDraw uses the dest blit key from the SOURCE surface ! */
601 ok(lpData[0] == 0x00ff0000 &&
602 lpData[1] == 0x00ff0000 &&
603 lpData[2] == 0x00001100 &&
604 lpData[3] == 0x00001100 &&
605 lpData[4] == 0x00001100 && /* Key applies here */
606 lpData[5] == 0x00110000, /* Key applies here */
607 "Surface data after dest key blit does not match\n");
609 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
610 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
611 lpData[2] = 0x00001100; /* Dest key in override */
612 lpData[3] = 0x00001100; /* Dest key in override */
613 lpData[4] = 0x00000000; /* Dest key in src surface */
614 lpData[5] = 0x00000000; /* Dest key in src surface */
615 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
616 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
618 /* Dest override key blit */
619 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
620 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
622 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
623 ok(rc==DD_OK,"Lock returned: %x\n",rc);
624 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
625 lpData = ddsd2.lpSurface;
627 ok(lpData[0] == 0x00FF0000 &&
628 lpData[1] == 0x00FF0000 &&
629 lpData[2] == 0x00FF0000 && /* Key applies here */
630 lpData[3] == 0x0000FF00 && /* Key applies here */
631 lpData[4] == 0x00000000 &&
632 lpData[5] == 0x00000000,
633 "Surface data after dest key override blit does not match\n");
635 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
636 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
637 lpData[2] = 0x00001100; /* Dest key in override */
638 lpData[3] = 0x00001100; /* Dest key in override */
639 lpData[4] = 0x00000000; /* Dest key in src surface */
640 lpData[5] = 0x00000000; /* Dest key in src surface */
641 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
642 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
644 /* Dest override key blit. Supposed to fail too */
645 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYDESTOVERRIDE, &fx);
646 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
648 /* Check for unchanged data */
649 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
650 ok(rc==DD_OK,"Lock returned: %x\n",rc);
651 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
652 lpData = ddsd2.lpSurface;
654 ok(lpData[0] == 0x00FF0000 &&
655 lpData[1] == 0x00FF0000 &&
656 lpData[2] == 0x00001100 && /* Key applies here */
657 lpData[3] == 0x00001100 && /* Key applies here */
658 lpData[4] == 0x00000000 &&
659 lpData[5] == 0x00000000,
660 "Surface data with dest key and dest override does not match\n");
662 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
663 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
664 lpData[2] = 0x00001100; /* Dest key in override */
665 lpData[3] = 0x00001100; /* Dest key in override */
666 lpData[4] = 0x00000000; /* Dest key in src surface */
667 lpData[5] = 0x00000000; /* Dest key in src surface */
668 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
669 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
671 /* Modify the source data a bit to give some more conclusive results */
672 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
673 ok(rc==DD_OK,"Lock returned: %x\n",rc);
674 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
675 lpData = ddsd2.lpSurface;
676 lpData[5] = 0x000000FF; /* Applies to src blt key in src surface */
677 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
678 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
680 /* Source and destination key */
681 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYSRC, &fx);
682 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
684 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
685 ok(rc==DD_OK,"Lock returned: %x\n",rc);
686 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
687 lpData = ddsd2.lpSurface;
689 ok(lpData[0] == 0x00FF0000 && /* Masked by Destination key */
690 lpData[1] == 0x00FF0000 && /* Masked by Destination key */
691 lpData[2] == 0x00001100 && /* Masked by Destination key */
692 lpData[3] == 0x00001100 && /* Masked by Destination key */
693 lpData[4] == 0x00001100 && /* Allowed by destination key, not masked by source key */
694 lpData[5] == 0x00000000, /* Allowed by dst key, but masked by source key */
695 "Surface data with src key and dest key blit does not match\n");
697 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
698 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
699 lpData[2] = 0x00001100; /* Dest key in override */
700 lpData[3] = 0x00001100; /* Dest key in override */
701 lpData[4] = 0x00000000; /* Dest key in src surface */
702 lpData[5] = 0x00000000; /* Dest key in src surface */
703 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
704 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
706 /* Override keys without ddbltfx parameter fail */
707 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, NULL);
708 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
709 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, NULL);
710 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
712 /* Try blitting without keys in the source surface*/
713 rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, NULL);
714 ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
715 rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_DESTBLT, NULL);
716 ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
718 /* That fails now. Do not bother to check that the data is unmodified */
719 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
720 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
722 /* Dest key blit still works. Which key is used this time??? */
723 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
724 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
726 /* With correctly passed override keys no key in the surface is needed.
727 * Again, the result was checked before, no need to do that again
729 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
730 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
731 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
732 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
734 IDirectDrawSurface_Release(lpSrc);
735 IDirectDrawSurface_Release(lpDst);
738 static void QueryInterface(void)
740 LPDIRECTDRAWSURFACE dsurface;
741 DDSURFACEDESC surface;
745 /* Create a surface */
746 ZeroMemory(&surface, sizeof(surface));
747 surface.dwSize = sizeof(surface);
748 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
749 surface.dwHeight = 10;
750 surface.dwWidth = 10;
751 ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
754 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
758 /* Call IUnknown::QueryInterface */
759 ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
760 ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %x\n", ret);
762 IDirectDrawSurface_Release(dsurface);
765 /* The following tests test which interface is returned by IDirectDrawSurfaceX::GetDDInterface.
766 * It uses refcounts to test that and compares the interface addresses. Partially fits here, and
767 * partially in the refcount test
770 static ULONG getref(IUnknown *iface)
772 IUnknown_AddRef(iface);
773 return IUnknown_Release(iface);
776 static void GetDDInterface_1(void)
778 LPDIRECTDRAWSURFACE dsurface;
779 LPDIRECTDRAWSURFACE2 dsurface2;
780 DDSURFACEDESC surface;
785 ULONG ref1, ref2, ref4, ref7;
788 /* Create a surface */
789 ZeroMemory(&surface, sizeof(surface));
790 surface.dwSize = sizeof(surface);
791 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
792 surface.dwHeight = 10;
793 surface.dwWidth = 10;
794 ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
797 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
800 ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
801 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
802 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
803 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
804 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
805 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
806 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
807 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
809 ref1 = getref((IUnknown *) lpDD);
810 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
811 ref2 = getref((IUnknown *) dd2);
812 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
813 ref4 = getref((IUnknown *) dd4);
814 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
815 ref7 = getref((IUnknown *) dd7);
816 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
819 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
820 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
821 ok(getref((IUnknown *) lpDD) == ref1 + 1, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
822 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
823 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
824 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
826 ok(dd == lpDD, "Returned interface pointer is not equal to the creation interface\n");
827 IUnknown_Release((IUnknown *) dd);
829 /* try a NULL pointer */
830 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, NULL);
831 ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
833 IDirectDraw_Release(dd2);
834 IDirectDraw_Release(dd4);
835 IDirectDraw_Release(dd7);
836 IDirectDrawSurface2_Release(dsurface2);
837 IDirectDrawSurface_Release(dsurface);
840 static void GetDDInterface_2(void)
842 LPDIRECTDRAWSURFACE dsurface;
843 LPDIRECTDRAWSURFACE2 dsurface2;
844 DDSURFACEDESC surface;
849 ULONG ref1, ref2, ref4, ref7;
852 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
853 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
854 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
855 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
856 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
857 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
859 /* Create a surface */
860 ZeroMemory(&surface, sizeof(surface));
861 surface.dwSize = sizeof(surface);
862 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
863 surface.dwHeight = 10;
864 surface.dwWidth = 10;
865 ret = IDirectDraw2_CreateSurface(dd2, &surface, &dsurface, NULL);
868 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
871 ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
872 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
874 ref1 = getref((IUnknown *) lpDD);
875 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
876 ref2 = getref((IUnknown *) dd2);
877 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
878 ref4 = getref((IUnknown *) dd4);
879 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
880 ref7 = getref((IUnknown *) dd7);
881 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
884 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
885 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
886 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
887 ok(getref((IUnknown *) dd2) == ref2 + 1, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
888 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
889 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
891 ok(dd == dd2, "Returned interface pointer is not equal to the creation interface\n");
892 IUnknown_Release((IUnknown *) dd);
894 IDirectDraw_Release(dd2);
895 IDirectDraw_Release(dd4);
896 IDirectDraw_Release(dd7);
897 IDirectDrawSurface2_Release(dsurface2);
898 IDirectDrawSurface_Release(dsurface);
901 static void GetDDInterface_4(void)
903 LPDIRECTDRAWSURFACE2 dsurface2;
904 LPDIRECTDRAWSURFACE4 dsurface4;
905 DDSURFACEDESC2 surface;
910 ULONG ref1, ref2, ref4, ref7;
913 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
914 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
915 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
916 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
917 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
918 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
920 /* Create a surface */
921 ZeroMemory(&surface, sizeof(surface));
922 surface.dwSize = sizeof(surface);
923 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
924 surface.dwHeight = 10;
925 surface.dwWidth = 10;
926 ret = IDirectDraw4_CreateSurface(dd4, &surface, &dsurface4, NULL);
929 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
932 ret = IDirectDrawSurface4_QueryInterface(dsurface4, &IID_IDirectDrawSurface2, (void **) &dsurface2);
933 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
935 ref1 = getref((IUnknown *) lpDD);
936 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
937 ref2 = getref((IUnknown *) dd2);
938 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
939 ref4 = getref((IUnknown *) dd4);
940 ok(ref4 == 2, "IDirectDraw4 refcount is %d\n", ref4);
941 ref7 = getref((IUnknown *) dd7);
942 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
944 ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
945 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
946 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
947 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
948 ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
949 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
951 ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
952 IUnknown_Release((IUnknown *) dd);
954 /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
955 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
956 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
957 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
958 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
959 ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
960 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
962 ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
963 IUnknown_Release((IUnknown *) dd);
965 IDirectDraw_Release(dd2);
966 IDirectDraw_Release(dd4);
967 IDirectDraw_Release(dd7);
968 IDirectDrawSurface4_Release(dsurface4);
969 IDirectDrawSurface2_Release(dsurface2);
972 static void GetDDInterface_7(void)
974 LPDIRECTDRAWSURFACE4 dsurface4;
975 LPDIRECTDRAWSURFACE7 dsurface7;
976 DDSURFACEDESC2 surface;
981 ULONG ref1, ref2, ref4, ref7;
984 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
985 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
986 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
987 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
988 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
989 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
991 /* Create a surface */
992 ZeroMemory(&surface, sizeof(surface));
993 surface.dwSize = sizeof(surface);
994 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
995 surface.dwHeight = 10;
996 surface.dwWidth = 10;
997 ret = IDirectDraw7_CreateSurface(dd7, &surface, &dsurface7, NULL);
1000 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
1003 ret = IDirectDrawSurface7_QueryInterface(dsurface7, &IID_IDirectDrawSurface4, (void **) &dsurface4);
1004 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
1006 ref1 = getref((IUnknown *) lpDD);
1007 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
1008 ref2 = getref((IUnknown *) dd2);
1009 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
1010 ref4 = getref((IUnknown *) dd4);
1011 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
1012 ref7 = getref((IUnknown *) dd7);
1013 ok(ref7 == 2, "IDirectDraw7 refcount is %d\n", ref7);
1015 ret = IDirectDrawSurface7_GetDDInterface(dsurface7, &dd);
1016 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1017 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1018 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1019 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1020 ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1022 ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1023 IUnknown_Release((IUnknown *) dd);
1025 /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
1026 ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
1027 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1028 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1029 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1030 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1031 ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1033 ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1034 IUnknown_Release((IUnknown *) dd);
1036 IDirectDraw_Release(dd2);
1037 IDirectDraw_Release(dd4);
1038 IDirectDraw_Release(dd7);
1039 IDirectDrawSurface4_Release(dsurface4);
1040 IDirectDrawSurface7_Release(dsurface7);
1043 static ULONG getRefcount(IUnknown *iface)
1045 IUnknown_AddRef(iface);
1046 return IUnknown_Release(iface);
1049 static void IFaceRefCount(void)
1051 LPDIRECTDRAWSURFACE surf;
1052 DDSURFACEDESC surface;
1054 IDirectDrawSurface2 *surf2;
1055 IDirectDrawSurface2 *surf2a;
1056 IDirectDrawSurface4 *surf4;
1057 IDirectDrawSurface7 *surf7a;
1058 IDirectDrawSurface7 *surf7b;
1059 IDirect3DTexture* tex;
1060 IDirect3DTexture2* tex2;
1061 IDirectDrawGammaControl* gamma;
1064 /* Create a surface */
1065 ZeroMemory(&surface, sizeof(surface));
1066 surface.dwSize = sizeof(surface);
1067 surface.dwFlags = DDSD_CAPS;
1068 surface.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1069 ret = IDirectDraw_CreateSurface(lpDD, &surface, &surf, NULL);
1073 ok(FALSE, "Could not create surface, skipping test\n");
1077 ref = getRefcount((IUnknown *) surf);
1078 ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
1080 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
1081 ref = getRefcount((IUnknown *) surf);
1082 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
1083 ref = getRefcount((IUnknown *) surf2);
1084 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* This should also be one */
1086 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2a);
1087 ref = getRefcount((IUnknown *) surf2);
1088 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref); /* Surf2's refcount should be 2 now, but surf should be 1 */
1089 ref = getRefcount((IUnknown *) surf);
1090 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1092 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface4, (void **) &surf4);
1093 ref = getRefcount((IUnknown *) surf4);
1094 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1096 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7a);
1097 ref = getRefcount((IUnknown *) surf7a);
1098 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1100 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7b);
1101 ref = getRefcount((IUnknown *) surf7b);
1102 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1104 /* IDirect3DTexture interface (unlike the others) alters the original IDirectDrawSurface ref count */
1105 ret = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture, (void **) &tex);
1108 ref = getRefcount((IUnknown *) tex);
1109 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1110 ref = getRefcount((IUnknown *) surf);
1111 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1113 IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture2, (void **) &tex2);
1114 ref = getRefcount((IUnknown *) tex);
1115 todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1116 ref = getRefcount((IUnknown *) tex2);
1117 todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1118 ref = getRefcount((IUnknown *) surf);
1119 todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1121 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawGammaControl, (void **) &gamma);
1122 ref = getRefcount((IUnknown *) gamma);
1123 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1125 ref = IDirect3DTexture2_Release(tex2); /* Release the texture */
1126 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1127 ref = getRefcount((IUnknown *) surf);
1128 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1130 ref = IDirect3DTexture_Release(tex); /* Release the texture */
1131 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1132 ref = getRefcount((IUnknown *) surf);
1133 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1135 ref = IDirectDrawGammaControl_Release(gamma); /* Release the gamma control */
1136 todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1139 ref = IDirectDrawSurface2_Release(surf2); /* Release one of the 2 surf2 interfaces */
1140 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1142 ref = IDirectDrawSurface2_Release(surf2a); /* Release the other */
1143 todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1145 ref = IDirectDrawSurface4_Release(surf4);
1146 todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1148 ref = IDirectDrawSurface7_Release(surf7a);
1149 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1151 ref = IDirectDrawSurface7_Release(surf7b);
1152 todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1154 ref = IDirectDrawSurface_Release(surf);
1155 ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1158 #define MAXEXPECTED 8 /* Can match up to 8 expected surfaces */
1161 IDirectDrawSurface *expected[MAXEXPECTED];
1165 static HRESULT WINAPI enumCB(IDirectDrawSurface *surf, DDSURFACEDESC *desc, void *ctx)
1170 for(i = 0; i < MAXEXPECTED; i++)
1172 if(((struct enumstruct *)ctx)->expected[i] == surf) found = TRUE;
1175 ok(found, "Unexpected surface %p enumerated\n", surf);
1176 ((struct enumstruct *)ctx)->count++;
1177 IDirectDrawSurface_Release(surf);
1178 return DDENUMRET_OK;
1181 static void EnumTest(void)
1185 IDirectDrawSurface *surface;
1186 struct enumstruct ctx;
1188 ddsd.dwSize = sizeof(ddsd);
1189 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1190 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1191 U2(ddsd).dwMipMapCount = 3;
1194 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
1195 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
1197 memset(&ctx, 0, sizeof(ctx));
1198 ctx.expected[0] = surface;
1199 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[0], &ddsd.ddsCaps, &ctx.expected[1]);
1200 ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1201 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[1], &ddsd.ddsCaps, &ctx.expected[2]);
1202 ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1203 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[2], &ddsd.ddsCaps, &ctx.expected[3]);
1204 ok(rc == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", rc);
1205 ok(!ctx.expected[3], "expected NULL pointer\n");
1208 rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, &ddsd, &ctx, enumCB);
1209 ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
1210 ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
1212 IDirectDrawSurface_Release(ctx.expected[2]);
1213 IDirectDrawSurface_Release(ctx.expected[1]);
1214 IDirectDrawSurface_Release(surface);
1217 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1219 UINT *num = context;
1221 IDirectDrawSurface_Release(surface);
1222 return DDENUMRET_OK;
1225 static void AttachmentTest7(void)
1229 IDirectDrawSurface7 *surface1, *surface2, *surface3, *surface4;
1230 DDSURFACEDESC2 ddsd, ddsd2;
1232 DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0}, caps2 = {DDSCAPS_BACKBUFFER,0,0,0};
1233 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1235 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1236 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1238 memset(&ddsd, 0, sizeof(ddsd));
1239 ddsd.dwSize = sizeof(ddsd);
1240 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1241 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1242 U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1244 ddsd.dwHeight = 128;
1245 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1246 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1250 IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1251 ok(num == 1, "Mipmap root has %d surfaces attached, expected 1\n", num);
1255 hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1256 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1258 IDirectDrawSurface7_EnumAttachedSurfaces(surface2, &num, SurfaceCounter);
1259 ok(num == 1, "First mip level has %d surfaces attached, expected 1\n", num);
1263 hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1264 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1265 IDirectDrawSurface7_Release(surface2);
1267 IDirectDrawSurface7_EnumAttachedSurfaces(surface3, &num, SurfaceCounter);
1268 ok(num == 0, "Second mip level has %d surfaces attached, expected 1\n", num);
1270 /* Mip level 3 is still needed */
1271 hr = IDirectDrawSurface7_GetAttachedSurface(surface3, &caps, &surface4);
1272 ok(hr == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", hr);
1273 ok(!surface4, "expected NULL pointer\n");
1275 /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1276 memset(&ddsd, 0, sizeof(ddsd));
1277 ddsd.dwSize = sizeof(ddsd);
1278 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1279 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1282 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1283 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1285 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1286 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1287 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1288 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1289 hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1290 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1291 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1292 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1294 IDirectDrawSurface7_Release(surface2);
1296 memset(&ddsd, 0, sizeof(ddsd));
1297 ddsd.dwSize = sizeof(ddsd);
1298 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1299 ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1302 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1303 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1305 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1306 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1307 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1308 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1309 hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1310 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1311 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1312 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1314 IDirectDrawSurface7_Release(surface3);
1315 IDirectDrawSurface7_Release(surface2);
1316 IDirectDrawSurface7_Release(surface1);
1318 hr = IDirectDraw7_SetCooperativeLevel(dd7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1319 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1321 memset(&ddsd, 0, sizeof(ddsd));
1322 ddsd.dwSize = sizeof(ddsd);
1323 ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
1324 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
1325 ddsd.dwBackBufferCount = 2;
1326 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1327 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1329 /* backbuffer surfaces must not have dwBackBufferCount set */
1330 ddsd2.dwSize = sizeof(ddsd2);
1331 hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps2, &surface2);
1332 ok(hr==DD_OK,"GetAttachedSurface returned: %x\n", hr);
1333 hr = IDirectDrawSurface7_GetSurfaceDesc(surface2, &ddsd2);
1334 ok(hr==DD_OK,"GetSurfaceDesc returned: %x\n", hr);
1335 ok(ddsd2.dwBackBufferCount==0,"backbuffer surface has dwBackBufferCount==%u\n", ddsd2.dwBackBufferCount);
1338 IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1339 ok(num == 1, "Primary surface has %d surfaces attached, expected 1\n", num);
1340 IDirectDrawSurface7_Release(surface1);
1342 /* Those are some invalid descriptions, no need to test attachments with them */
1343 memset(&ddsd, 0, sizeof(ddsd));
1344 ddsd.dwSize = sizeof(ddsd);
1345 ddsd.dwFlags = DDSD_CAPS;
1346 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1347 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1348 ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1349 memset(&ddsd, 0, sizeof(ddsd));
1350 ddsd.dwSize = sizeof(ddsd);
1351 ddsd.dwFlags = DDSD_CAPS;
1352 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1353 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1354 ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1356 /* Try a single primary and two offscreen plain surfaces */
1357 memset(&ddsd, 0, sizeof(ddsd));
1358 ddsd.dwSize = sizeof(ddsd);
1359 ddsd.dwFlags = DDSD_CAPS;
1360 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1361 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1362 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1364 memset(&ddsd, 0, sizeof(ddsd));
1365 ddsd.dwSize = sizeof(ddsd);
1366 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1367 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1368 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1369 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1370 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1371 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1373 memset(&ddsd, 0, sizeof(ddsd));
1374 ddsd.dwSize = sizeof(ddsd);
1375 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1376 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1377 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1378 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1379 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface3, NULL);
1380 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1382 /* This one has a different size */
1383 memset(&ddsd, 0, sizeof(ddsd));
1384 ddsd.dwSize = sizeof(ddsd);
1385 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1386 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1388 ddsd.dwHeight = 128;
1389 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface4, NULL);
1390 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1392 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1393 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1394 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1395 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1396 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1397 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1398 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1399 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1400 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1401 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1403 IDirectDrawSurface7_Release(surface4);
1404 IDirectDrawSurface7_Release(surface3);
1405 IDirectDrawSurface7_Release(surface2);
1406 IDirectDrawSurface7_Release(surface1);
1408 hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL);
1409 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1410 IDirectDraw7_Release(dd7);
1413 static void AttachmentTest(void)
1416 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
1418 DDSCAPS caps = {DDSCAPS_TEXTURE};
1419 BOOL refrast = FALSE;
1420 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1422 memset(&ddsd, 0, sizeof(ddsd));
1423 ddsd.dwSize = sizeof(ddsd);
1424 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1425 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1426 U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1428 ddsd.dwHeight = 128;
1429 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1430 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1432 hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1433 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1434 hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1435 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1437 /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1438 memset(&ddsd, 0, sizeof(ddsd));
1439 ddsd.dwSize = sizeof(ddsd);
1440 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1441 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1444 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1445 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1447 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1448 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1449 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1450 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1451 hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
1452 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1453 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1454 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1455 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
1456 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 64x64 texture sublevel returned %08x\n", hr);
1457 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1458 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 texture returned %08x\n", hr);
1460 IDirectDrawSurface7_Release(surface4);
1462 memset(&ddsd, 0, sizeof(ddsd));
1463 ddsd.dwSize = sizeof(ddsd);
1464 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1465 ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1468 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1469 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1471 if (SUCCEEDED(IDirectDrawSurface7_AddAttachedSurface(surface1, surface4)))
1473 IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1477 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4); /* Succeeds on refrast */
1479 ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1481 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1482 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1484 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1); /* Succeeds on refrast */
1486 ok(hr == S_OK, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1488 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1489 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface1);
1491 hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4); /* Succeeds on refrast */
1493 ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1495 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1496 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface3, 0, surface4);
1498 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1499 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1500 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface3);
1502 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4); /* Succeeds on refrast */
1504 ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1506 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1507 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface2, 0, surface4);
1509 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1510 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 offscreen plain surface returned %08x\n", hr);
1511 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface2);
1513 IDirectDrawSurface7_Release(surface4);
1514 IDirectDrawSurface7_Release(surface3);
1515 IDirectDrawSurface7_Release(surface2);
1516 IDirectDrawSurface7_Release(surface1);
1518 hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1519 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1521 /* Creating a back buffer as-is, is not allowed. No need to perform attachment tests */
1522 memset(&ddsd, 0, sizeof(ddsd));
1523 ddsd.dwSize = sizeof(ddsd);
1524 ddsd.dwFlags = DDSD_CAPS;
1525 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1526 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1527 ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1528 /* This old ddraw version happily creates explicit front buffers */
1529 memset(&ddsd, 0, sizeof(ddsd));
1530 ddsd.dwSize = sizeof(ddsd);
1531 ddsd.dwFlags = DDSD_CAPS;
1532 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1533 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1534 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1535 IDirectDrawSurface_Release(surface1);
1537 /* Try a single primary and two offscreen plain surfaces */
1538 memset(&ddsd, 0, sizeof(ddsd));
1539 ddsd.dwSize = sizeof(ddsd);
1540 ddsd.dwFlags = DDSD_CAPS;
1541 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1542 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1543 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1545 memset(&ddsd, 0, sizeof(ddsd));
1546 ddsd.dwSize = sizeof(ddsd);
1547 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1548 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1549 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1550 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1551 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1552 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1554 memset(&ddsd, 0, sizeof(ddsd));
1555 ddsd.dwSize = sizeof(ddsd);
1556 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1557 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1558 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1559 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1560 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
1561 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1563 /* This one has a different size */
1564 memset(&ddsd, 0, sizeof(ddsd));
1565 ddsd.dwSize = sizeof(ddsd);
1566 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1567 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1569 ddsd.dwHeight = 128;
1570 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1571 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1573 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
1574 ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1575 "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1578 /* Try the reverse without detaching first */
1579 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1580 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
1581 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1582 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1584 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1585 ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1586 "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1589 /* Try to detach reversed */
1590 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1591 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
1592 /* Now the proper detach */
1593 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
1594 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1596 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3); /* Fails on refrast */
1597 ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1598 "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1601 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
1602 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1604 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
1605 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1606 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
1607 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1609 IDirectDrawSurface_Release(surface4);
1610 IDirectDrawSurface_Release(surface3);
1611 IDirectDrawSurface_Release(surface2);
1612 IDirectDrawSurface_Release(surface1);
1614 hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
1615 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1617 DestroyWindow(window);
1622 DWORD width, height;
1627 static HRESULT WINAPI CubeTestLvl2Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1629 UINT *mips = context;
1632 IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1636 return DDENUMRET_OK;
1639 static HRESULT WINAPI CubeTestLvl1Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1642 UINT *num = context;
1643 static const struct compare expected[] =
1647 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1648 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ,
1653 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1654 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ,
1659 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1660 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY,
1665 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1666 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY,
1671 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1672 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX,
1676 64, 64, /* This is the first mipmap */
1677 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1678 DDSCAPS2_MIPMAPSUBLEVEL | DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX,
1684 IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1688 ok(desc->dwWidth == expected[*num].width, "Surface width is %d expected %d\n", desc->dwWidth, expected[*num].width);
1689 ok(desc->dwHeight == expected[*num].height, "Surface height is %d expected %d\n", desc->dwHeight, expected[*num].height);
1690 ok(desc->ddsCaps.dwCaps == expected[*num].caps, "Surface caps are %08x expected %08x\n", desc->ddsCaps.dwCaps, expected[*num].caps);
1691 ok(desc->ddsCaps.dwCaps2 == expected[*num].caps2, "Surface caps2 are %08x expected %08x\n", desc->ddsCaps.dwCaps2, expected[*num].caps2);
1692 ok(mips == expected[*num].mips, "Surface has %d mipmaps, expected %d\n", mips, expected[*num].mips);
1696 IDirectDrawSurface7_Release(surface);
1698 return DDENUMRET_OK;
1701 static void CubeMapTest(void)
1703 IDirectDraw7 *dd7 = NULL;
1704 IDirectDrawSurface7 *cubemap = NULL;
1705 DDSURFACEDESC2 ddsd;
1708 struct enumstruct ctx;
1710 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1711 ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1712 if (FAILED(hr)) goto err;
1714 memset(&ddsd, 0, sizeof(ddsd));
1715 ddsd.dwSize = sizeof(ddsd);
1716 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1717 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1719 ddsd.dwHeight = 128;
1720 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1721 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1724 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1725 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1726 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1727 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1728 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1730 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1733 skip("Can't create cubemap surface\n");
1737 hr = IDirectDrawSurface7_GetSurfaceDesc(cubemap, &ddsd);
1738 ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
1739 ok(ddsd.ddsCaps.dwCaps == (DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX),
1740 "Root Caps are %08x\n", ddsd.ddsCaps.dwCaps);
1741 ok(ddsd.ddsCaps.dwCaps2 == (DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP),
1742 "Root Caps2 are %08x\n", ddsd.ddsCaps.dwCaps2);
1744 IDirectDrawSurface7_EnumAttachedSurfaces(cubemap,
1747 ok(num == 6, "Surface has %d attachments\n", num);
1748 IDirectDrawSurface7_Release(cubemap);
1750 /* What happens if I do not specify any faces? */
1751 memset(&ddsd, 0, sizeof(ddsd));
1752 ddsd.dwSize = sizeof(ddsd);
1753 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1754 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1756 ddsd.dwHeight = 128;
1757 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1758 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP;
1761 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1762 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1763 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1764 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1765 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1767 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1768 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7::CreateSurface asking for a cube map without faces returned %08x\n", hr);
1770 /* Cube map faces without a cube map? */
1771 memset(&ddsd, 0, sizeof(ddsd));
1772 ddsd.dwSize = sizeof(ddsd);
1773 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1774 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1776 ddsd.dwHeight = 128;
1777 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1778 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_ALLFACES;
1781 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1782 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1783 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1784 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1785 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1787 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1788 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1790 memset(&ddsd, 0, sizeof(ddsd));
1791 ddsd.dwSize = sizeof(ddsd);
1792 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1793 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1795 ddsd.dwHeight = 128;
1796 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1797 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEX;
1800 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1801 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1802 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1803 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1804 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1806 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1807 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1809 /* Make sure everything is cleaned up properly. Use the enumSurfaces test infrastructure */
1810 memset(&ctx, 0, sizeof(ctx));
1811 memset(&ddsd, 0, sizeof(ddsd));
1812 ddsd.dwSize = sizeof(DDSURFACEDESC);
1813 hr = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, (DDSURFACEDESC *) &ddsd, (void *) &ctx, enumCB);
1814 ok(hr == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", hr);
1815 ok(ctx.count == 0, "%d surfaces enumerated, expected 0\n", ctx.count);
1818 if (dd7) IDirectDraw7_Release(dd7);
1821 static void test_lockrect_invalid(void)
1834 {68, 60, 60, 68}, /* left > right */
1835 {60, 68, 68, 60}, /* top > bottom */
1836 {-8, 60, 0, 68}, /* left < surface */
1837 {60, -8, 68, 0}, /* top < surface */
1838 {-16, 60, -8, 68}, /* right < surface */
1839 {60, -16, 68, -8}, /* bottom < surface */
1840 {60, 60, 136, 68}, /* right > surface */
1841 {60, 60, 68, 136}, /* bottom > surface */
1842 {136, 60, 144, 68}, /* left > surface */
1843 {60, 136, 68, 144}, /* top > surface */
1846 const DWORD dds_caps[] = {
1847 DDSCAPS_OFFSCREENPLAIN
1850 for (j = 0; j < (sizeof(dds_caps) / sizeof(*dds_caps)); ++j)
1852 IDirectDrawSurface *surface = 0;
1853 DDSURFACEDESC surface_desc = {0};
1854 DDSURFACEDESC locked_desc = {0};
1857 surface_desc.dwSize = sizeof(surface_desc);
1858 surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
1859 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1860 surface_desc.ddsCaps.dwCaps = dds_caps[j];
1861 surface_desc.dwWidth = 128;
1862 surface_desc.dwHeight = 128;
1863 surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
1864 U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
1865 U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xFF0000;
1866 U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00FF00;
1867 U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000FF;
1869 hr = IDirectDraw_CreateSurface(lpDD, &surface_desc, &surface, NULL);
1870 ok(SUCCEEDED(hr), "CreateSurface failed (0x%08x)\n", hr);
1873 skip("failed to create surface\n");
1877 for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i)
1879 RECT *rect = &valid[i];
1881 memset(&locked_desc, 0, sizeof(locked_desc));
1882 locked_desc.dwSize = sizeof(locked_desc);
1884 hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1885 ok(SUCCEEDED(hr), "Lock failed (0x%08x) for rect [%d, %d]->[%d, %d]\n",
1886 hr, rect->left, rect->top, rect->right, rect->bottom);
1888 hr = IDirectDrawSurface_Unlock(surface, NULL);
1889 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1892 for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i)
1894 RECT *rect = &invalid[i];
1896 memset(&locked_desc, 1, sizeof(locked_desc));
1897 locked_desc.dwSize = sizeof(locked_desc);
1899 hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1900 ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for rect [%d, %d]->[%d, %d]"
1901 ", expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, rect->left, rect->top,
1902 rect->right, rect->bottom, DDERR_INVALIDPARAMS);
1903 ok(!locked_desc.lpSurface, "IDirectDrawSurface_Lock did not set lpSurface in the surface desc to zero.\n");
1906 hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1907 ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = NULL) failed (0x%08x)\n", hr);
1908 hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1909 ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned 0x%08x\n", hr);
1911 hr = IDirectDrawSurface_Unlock(surface, NULL);
1912 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1914 hr = IDirectDrawSurface_Unlock(surface, NULL);
1915 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1917 memset(&locked_desc, 0, sizeof(locked_desc));
1918 locked_desc.dwSize = sizeof(locked_desc);
1919 hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1920 ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1921 valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1922 hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1923 ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1924 valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1926 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
1927 * Afterwards unlocking the surface fails(NULL rectangle, and both locked rectangles
1930 hr = IDirectDrawSurface_Unlock(surface, NULL);
1931 ok(hr == DD_OK, "Unlock returned (0x%08x)\n", hr);
1933 IDirectDrawSurface_Release(surface);
1937 static void CompressedTest(void)
1940 IDirectDrawSurface7 *surface;
1941 DDSURFACEDESC2 ddsd, ddsd2;
1942 IDirectDraw7 *dd7 = NULL;
1943 RECT r = { 0, 0, 128, 128 };
1944 RECT r2 = { 32, 32, 64, 64 };
1946 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1947 ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1949 memset(&ddsd, 0, sizeof(ddsd));
1950 ddsd.dwSize = sizeof(ddsd);
1951 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1952 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1954 ddsd.dwHeight = 128;
1955 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
1956 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
1957 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1959 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1960 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1963 skip("failed to create surface\n");
1967 memset(&ddsd2, 0, sizeof(ddsd2));
1968 ddsd2.dwSize = sizeof(ddsd2);
1969 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1970 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1971 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1973 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1974 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1975 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1976 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1977 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1978 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1979 ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1980 ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1981 IDirectDrawSurface7_Release(surface);
1983 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1984 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1985 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1988 skip("failed to create surface\n");
1992 memset(&ddsd2, 0, sizeof(ddsd2));
1993 ddsd2.dwSize = sizeof(ddsd2);
1994 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1995 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1996 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1998 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1999 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2000 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2001 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2002 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2003 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2004 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2005 IDirectDrawSurface7_Release(surface);
2007 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2008 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2009 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2012 skip("failed to create surface\n");
2016 memset(&ddsd2, 0, sizeof(ddsd2));
2017 ddsd2.dwSize = sizeof(ddsd2);
2018 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2019 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2020 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2022 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2023 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2024 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2025 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2026 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2027 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2028 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2029 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2031 memset(&ddsd2, 0, sizeof(ddsd2));
2032 ddsd2.dwSize = sizeof(ddsd2);
2033 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2035 /* Show that the description is not changed when locking the surface. What is really interesting
2036 * about this is that DDSD_LPSURFACE isn't set.
2038 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2039 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2041 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2042 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2043 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2044 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2045 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2046 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2047 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2048 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2050 hr = IDirectDrawSurface7_Unlock(surface, NULL);
2051 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2053 /* Now what about a locking rect? */
2054 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2055 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2057 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2058 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2059 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2060 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2061 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2062 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2063 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2064 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2066 hr = IDirectDrawSurface7_Unlock(surface, &r);
2067 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2069 /* Now what about a different locking offset? */
2070 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2071 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2073 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2074 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2075 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2076 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2077 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2078 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2079 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2080 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2082 hr = IDirectDrawSurface7_Unlock(surface, &r2);
2083 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2084 IDirectDrawSurface7_Release(surface);
2086 /* Try this with video memory. A kind of surprise. It still has the LINEARSIZE flag set,
2087 * but seems to have a pitch instead.
2089 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
2090 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2092 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2093 ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW || hr == DDERR_INVALIDPARAMS ||
2094 broken(hr == DDERR_NODIRECTDRAWHW), "CreateSurface returned %08x\n", hr);
2096 /* Not supported everywhere */
2099 memset(&ddsd2, 0, sizeof(ddsd2));
2100 ddsd2.dwSize = sizeof(ddsd2);
2101 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2102 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2103 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2105 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2106 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2107 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2108 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2109 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2110 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2111 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2112 ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2113 IDirectDrawSurface7_Release(surface);
2115 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2116 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2117 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2119 memset(&ddsd2, 0, sizeof(ddsd2));
2120 ddsd2.dwSize = sizeof(ddsd2);
2121 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2122 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2123 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2125 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2126 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2127 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2128 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2129 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2130 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2131 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2132 IDirectDrawSurface7_Release(surface);
2134 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2135 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2136 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2138 memset(&ddsd2, 0, sizeof(ddsd2));
2139 ddsd2.dwSize = sizeof(ddsd2);
2140 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2141 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2142 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2144 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2145 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2146 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2147 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2148 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2149 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2150 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2151 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2153 memset(&ddsd2, 0, sizeof(ddsd2));
2154 ddsd2.dwSize = sizeof(ddsd2);
2155 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2157 /* Show that the description is not changed when locking the surface. What is really interesting
2158 * about this is that DDSD_LPSURFACE isn't set.
2160 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2161 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2163 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2164 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2165 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2166 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2167 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2168 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2169 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2170 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2172 hr = IDirectDrawSurface7_Unlock(surface, NULL);
2173 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2175 /* Now what about a locking rect? */
2176 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2177 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2179 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2180 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2181 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2182 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2183 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2184 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2185 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2186 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2188 hr = IDirectDrawSurface7_Unlock(surface, &r);
2189 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2191 /* Now what about a different locking offset? */
2192 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2193 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2195 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2196 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2197 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2198 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2199 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2200 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2201 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2202 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2204 hr = IDirectDrawSurface7_Unlock(surface, &r2);
2205 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2207 IDirectDrawSurface7_Release(surface);
2211 skip("Hardware DXTN textures not supported\n");
2214 /* What happens to managed textures? Interestingly, Windows reports them as being in system
2215 * memory. The linear size fits again.
2217 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2218 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
2219 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2221 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2222 ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW, "CreateSurface returned %08x\n", hr);
2224 /* Not supported everywhere */
2227 memset(&ddsd2, 0, sizeof(ddsd2));
2228 ddsd2.dwSize = sizeof(ddsd2);
2229 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2230 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2231 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2233 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2234 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2235 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2236 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2237 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2238 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2239 ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2240 ok(ddsd2.ddsCaps.dwCaps2 == DDSCAPS2_TEXTUREMANAGE, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2241 IDirectDrawSurface7_Release(surface);
2243 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2244 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2245 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2247 memset(&ddsd2, 0, sizeof(ddsd2));
2248 ddsd2.dwSize = sizeof(ddsd2);
2249 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2250 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2251 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2253 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2254 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2255 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2256 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2257 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2258 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2259 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2260 IDirectDrawSurface7_Release(surface);
2262 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2263 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2264 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2266 memset(&ddsd2, 0, sizeof(ddsd2));
2267 ddsd2.dwSize = sizeof(ddsd2);
2268 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2269 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2270 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2272 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2273 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2274 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2275 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2276 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2277 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2278 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2279 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2281 memset(&ddsd2, 0, sizeof(ddsd2));
2282 ddsd2.dwSize = sizeof(ddsd2);
2283 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2285 /* Show that the description is not changed when locking the surface. What is really interesting
2286 * about this is that DDSD_LPSURFACE isn't set.
2288 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2289 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2291 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2292 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2293 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2294 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2295 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2296 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2297 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2298 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2300 hr = IDirectDrawSurface7_Unlock(surface, NULL);
2301 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2303 /* Now what about a locking rect? */
2304 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2305 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2307 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2308 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2309 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2310 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2311 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2312 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2313 ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2314 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2316 hr = IDirectDrawSurface7_Unlock(surface, &r);
2317 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2319 /* Now what about a different locking offset? */
2320 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2321 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2323 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2324 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2325 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2326 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2327 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2328 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2329 ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2330 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2332 hr = IDirectDrawSurface7_Unlock(surface, &r2);
2333 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2335 IDirectDrawSurface7_Release(surface);
2339 skip("Hardware DXTN textures not supported\n");
2342 IDirectDraw7_Release(dd7);
2345 static void SizeTest(void)
2347 LPDIRECTDRAWSURFACE dsurface = NULL;
2350 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2352 /* Create an offscreen surface surface without a size */
2353 ZeroMemory(&desc, sizeof(desc));
2354 desc.dwSize = sizeof(desc);
2355 desc.dwFlags = DDSD_CAPS;
2356 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2357 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2358 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without a size info returned %08x (dsurface=%p)\n", ret, dsurface);
2361 trace("Surface at %p\n", dsurface);
2362 IDirectDrawSurface_Release(dsurface);
2366 /* Create an offscreen surface surface with only a width parameter */
2367 ZeroMemory(&desc, sizeof(desc));
2368 desc.dwSize = sizeof(desc);
2369 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH;
2370 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2372 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2373 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without hight info returned %08x\n", ret);
2376 IDirectDrawSurface_Release(dsurface);
2380 /* Create an offscreen surface surface with only a height parameter */
2381 ZeroMemory(&desc, sizeof(desc));
2382 desc.dwSize = sizeof(desc);
2383 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT;
2384 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2385 desc.dwHeight = 128;
2386 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2387 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without width info returned %08x\n", ret);
2390 IDirectDrawSurface_Release(dsurface);
2395 ZeroMemory(&desc, sizeof(desc));
2396 desc.dwSize = sizeof(desc);
2397 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2398 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2399 desc.dwHeight = 128;
2401 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2402 ok(ret == DD_OK, "Creating an offscreen plain surface with width and height info returned %08x\n", ret);
2405 IDirectDrawSurface_Release(dsurface);
2409 /* Test a primary surface size */
2410 ret = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_NORMAL);
2411 ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2413 ZeroMemory(&desc, sizeof(desc));
2414 desc.dwSize = sizeof(desc);
2415 desc.dwFlags = DDSD_CAPS;
2416 desc.ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
2417 desc.dwHeight = 128; /* Keep them set to check what happens */
2418 desc.dwWidth = 128; /* Keep them set to check what happens */
2419 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2420 ok(ret == DD_OK, "Creating a primary surface without width and height info returned %08x\n", ret);
2423 ret = IDirectDrawSurface_GetSurfaceDesc(dsurface, &desc);
2424 ok(ret == DD_OK, "GetSurfaceDesc returned %x\n", ret);
2426 IDirectDrawSurface_Release(dsurface);
2429 ok(desc.dwFlags & DDSD_WIDTH, "Primary surface doesn't have width set\n");
2430 ok(desc.dwFlags & DDSD_HEIGHT, "Primary surface doesn't have height set\n");
2431 ok(desc.dwWidth == GetSystemMetrics(SM_CXSCREEN), "Surface width differs from screen width\n");
2432 ok(desc.dwHeight == GetSystemMetrics(SM_CYSCREEN), "Surface height differs from screen height\n");
2434 ret = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
2435 ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2438 static void PrivateDataTest(void)
2441 IDirectDrawSurface7 *surface7 = NULL;
2442 IDirectDrawSurface *surface = NULL;
2446 DWORD size = sizeof(IUnknown *);
2448 ZeroMemory(&desc, sizeof(desc));
2449 desc.dwSize = sizeof(desc);
2450 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2451 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2452 desc.dwHeight = 128;
2454 hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface, NULL);
2455 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2460 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **) &surface7);
2461 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2464 IDirectDrawSurface_Release(surface);
2469 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 0, DDSPD_IUNKNOWNPOINTER);
2470 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2471 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 5, DDSPD_IUNKNOWNPOINTER);
2472 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2473 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *) * 2, DDSPD_IUNKNOWNPOINTER);
2474 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2476 ref = getref((IUnknown *) lpDD);
2477 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 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 + 1, "Object reference is %d, expected %d\n", ref2, ref + 1);
2481 hr = IDirectDrawSurface7_FreePrivateData(surface7, &IID_IDirectDrawSurface7);
2482 ok(SUCCEEDED(hr), "IDirectDrawSurface7_FreePrivateData returned %#x.\n", hr);
2483 ref2 = getref((IUnknown *) lpDD);
2484 ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2486 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2487 ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2488 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, surface7, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2489 ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2490 ref2 = getref((IUnknown *) lpDD);
2491 ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2493 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2494 ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2495 hr = IDirectDrawSurface7_GetPrivateData(surface7, &IID_IDirectDrawSurface7, &ptr, &size);
2496 ok(hr == DD_OK, "IDirectDrawSurface7_GetPrivateData failed with %08x\n", hr);
2497 ref2 = getref((IUnknown *) lpDD);
2498 /* Object is NOT being addrefed */
2499 ok(ptr == (IUnknown *) lpDD, "Returned interface pointer is %p, expected %p\n", ptr, lpDD);
2500 ok(ref2 == ref + 1, "Object reference is %d, expected %d. ptr at %p, orig at %p\n", ref2, ref + 1, ptr, lpDD);
2502 IDirectDrawSurface_Release(surface);
2503 IDirectDrawSurface7_Release(surface7);
2505 /* Destroying the surface frees the held reference */
2506 ref2 = getref((IUnknown *) lpDD);
2507 ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2510 static void BltParamTest(void)
2512 IDirectDrawSurface *surface1 = NULL, *surface2 = NULL;
2516 RECT valid = {10, 10, 20, 20};
2517 RECT invalid1 = {20, 10, 10, 20};
2518 RECT invalid2 = {20, 20, 20, 20};
2519 RECT invalid3 = {-1, -1, 20, 20};
2520 RECT invalid4 = {60, 60, 70, 70};
2522 memset(&desc, 0, sizeof(desc));
2523 desc.dwSize = sizeof(desc);
2524 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2525 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2526 desc.dwHeight = 128;
2528 hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface1, NULL);
2529 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2533 hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface2, NULL);
2534 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2539 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, NULL, NULL, 0);
2540 ok(hr == DD_OK, "BltFast from NULL surface returned %08x\n", hr);
2542 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, NULL, 0);
2543 ok(hr == DD_OK, "BltFast from smaller to bigger surface returned %08x\n", hr);
2544 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, NULL, 0);
2545 ok(hr == DDERR_INVALIDRECT, "BltFast from bigger to smaller surface returned %08x\n", hr);
2546 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &valid, 0);
2547 ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle returned %08x\n", hr);
2548 hr = IDirectDrawSurface_BltFast(surface2, 60, 60, surface1, &valid, 0);
2549 ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2550 hr = IDirectDrawSurface_BltFast(surface1, 90, 90, surface2, NULL, 0);
2551 ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2553 hr = IDirectDrawSurface_BltFast(surface1, -10, 0, surface2, NULL, 0);
2554 ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
2555 hr = IDirectDrawSurface_BltFast(surface1, 0, -10, surface2, NULL, 0);
2556 ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
2557 hr = IDirectDrawSurface_BltFast(surface2, 20, 20, surface1, &valid, 0);
2558 ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle and offset returned %08x\n", hr);
2560 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid1, 0);
2561 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 1 returned %08x\n", hr);
2562 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid2, 0);
2563 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 2 returned %08x\n", hr);
2564 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid3, 0);
2565 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2566 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, &invalid4, 0);
2567 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2568 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface1, NULL, 0);
2569 ok(hr == DD_OK, "BltFast blitting a surface onto itself returned %08x\n", hr);
2571 /* Blt(non-fast) tests */
2572 memset(&BltFx, 0, sizeof(BltFx));
2573 BltFx.dwSize = sizeof(BltFx);
2574 U5(BltFx).dwFillColor = 0xaabbccdd;
2576 hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2577 ok(hr == DD_OK, "IDirectDrawSurface_Blt with a valid rectangle for color fill returned %08x\n", hr);
2578 hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, &invalid3, DDBLT_COLORFILL, &BltFx);
2579 ok(hr == DD_OK, "IDirectDrawSurface_Blt with a invalid, unused rectangle returned %08x\n", hr);
2580 hr = IDirectDrawSurface_Blt(surface2, &invalid1, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2581 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2582 hr = IDirectDrawSurface_Blt(surface2, &invalid2, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2583 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2584 hr = IDirectDrawSurface_Blt(surface2, &invalid3, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2585 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2586 hr = IDirectDrawSurface_Blt(surface2, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2587 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2589 /* Valid on surface 1 */
2590 hr = IDirectDrawSurface_Blt(surface1, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2591 ok(hr == DD_OK, "IDirectDrawSurface_Blt with a subrectangle fill returned %08x\n", hr);
2593 /* Works - stretched blit */
2594 hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, NULL, 0, NULL);
2595 ok(hr == DD_OK, "IDirectDrawSurface_Blt from a smaller to a bigger surface returned %08x\n", hr);
2596 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, NULL, 0, NULL);
2597 ok(hr == DD_OK, "IDirectDrawSurface_Blt from a bigger to a smaller surface %08x\n", hr);
2599 /* Invalid dest rects in sourced blits */
2600 hr = IDirectDrawSurface_Blt(surface2, &invalid1, surface1, NULL, 0, NULL);
2601 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2602 hr = IDirectDrawSurface_Blt(surface2, &invalid2, surface1, NULL, 0, NULL);
2603 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2604 hr = IDirectDrawSurface_Blt(surface2, &invalid3, surface1, NULL, 0, NULL);
2605 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2606 hr = IDirectDrawSurface_Blt(surface2, &invalid4, surface1, NULL, 0, NULL);
2607 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2609 /* Invalid src rects */
2610 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid1, 0, NULL);
2611 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2612 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid2, 0, NULL);
2613 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2614 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid3, 0, NULL);
2615 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2616 hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, &invalid4, 0, NULL);
2617 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2619 IDirectDrawSurface_Release(surface1);
2620 IDirectDrawSurface_Release(surface2);
2623 static void PaletteTest(void)
2626 LPDIRECTDRAWSURFACE lpSurf = NULL;
2628 IDirectDrawPalette *palette = NULL;
2629 PALETTEENTRY Table[256];
2630 PALETTEENTRY palEntries[256];
2633 for(i=0; i<256; i++)
2635 Table[i].peRed = 0xff;
2636 Table[i].peGreen = 0;
2637 Table[i].peBlue = 0;
2638 Table[i].peFlags = 0;
2641 /* Create a 8bit palette without DDPCAPS_ALLOW256 set */
2642 hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_8BIT, Table, &palette, NULL);
2643 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2644 if (FAILED(hr)) goto err;
2645 /* Read back the palette and verify the entries. Without DDPCAPS_ALLOW256 set
2646 / entry 0 and 255 should have been overwritten with black and white */
2647 IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2648 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2651 ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2652 "Palette entry 0 of a palette without DDPCAPS_ALLOW256 set should be (0,0,0) but it is (%d,%d,%d)\n",
2653 palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2654 ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2655 "Palette entry 255 of a palette without DDPCAPS_ALLOW256 set should be (255,255,255) but it is (%d,%d,%d)\n",
2656 palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2658 /* Entry 1-254 should contain red */
2659 for(i=1; i<255; i++)
2660 ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2661 "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2662 i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2665 /* CreatePalette without DDPCAPS_ALLOW256 ignores entry 0 and 255,
2666 / now check we are able to update the entries afterwards. */
2667 IDirectDrawPalette_SetEntries(palette , 0, 0, 256, &Table[0]);
2668 ok(hr == DD_OK, "SetEntries failed with %08x\n", hr);
2669 IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2670 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2673 ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2674 "Palette entry 0 should have been set to (0,0,0) but it contains (%d,%d,%d)\n",
2675 palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2676 ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2677 "Palette entry 255 should have been set to (255,255,255) but it contains (%d,%d,%d)\n",
2678 palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2680 IDirectDrawPalette_Release(palette);
2682 /* Create a 8bit palette with DDPCAPS_ALLOW256 set */
2683 hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
2684 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2685 if (FAILED(hr)) goto err;
2687 IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2688 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2691 /* All entries should contain red */
2692 for(i=0; i<256; i++)
2693 ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2694 "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2695 i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2698 /* Try to set palette to a non-palettized surface */
2699 ddsd.dwSize = sizeof(ddsd);
2700 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2701 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2702 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2704 ddsd.dwHeight = 600;
2705 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2706 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
2707 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
2708 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
2709 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
2710 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurf, NULL);
2711 ok(hr==DD_OK, "CreateSurface returned: %x\n",hr);
2714 skip("failed to create surface\n");
2718 hr = IDirectDrawSurface_SetPalette(lpSurf, palette);
2719 ok(hr == DDERR_INVALIDPIXELFORMAT, "CreateSurface returned: %x\n",hr);
2721 IDirectDrawPalette_Release(palette);
2724 hr = IDirectDrawSurface_GetPalette(lpSurf, &palette);
2725 ok(hr == DDERR_NOPALETTEATTACHED, "CreateSurface returned: %x\n",hr);
2729 if (lpSurf) IDirectDrawSurface_Release(lpSurf);
2730 if (palette) IDirectDrawPalette_Release(palette);
2733 static void StructSizeTest(void)
2735 IDirectDrawSurface *surface1;
2736 IDirectDrawSurface7 *surface7;
2738 DDSURFACEDESC desc1;
2739 DDSURFACEDESC2 desc2;
2740 char blob[1024]; /* To get a bunch of writable memory */
2742 DDSURFACEDESC create;
2745 memset(&desc, 0, sizeof(desc));
2746 memset(&create, 0, sizeof(create));
2748 memset(&create, 0, sizeof(create));
2749 create.dwSize = sizeof(create);
2750 create.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2751 create.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2752 create.dwHeight = 128;
2753 create.dwWidth = 128;
2754 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2755 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2756 hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface7, (void **) &surface7);
2757 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2759 desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2760 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2761 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2762 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2763 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2765 desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2766 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2767 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2768 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2769 ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2771 desc.desc2.dwSize = 0;
2772 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2773 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2774 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2775 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2777 desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2778 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2779 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2780 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2781 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2783 desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2784 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2785 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2786 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2787 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2789 /* Tests for Lock() */
2791 desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2792 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2793 ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2794 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2795 ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2796 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2797 ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2798 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2799 ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2801 desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2802 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2803 ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2804 ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2805 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2806 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2807 ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2808 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2809 ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2811 desc.desc2.dwSize = 0;
2812 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2813 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size 0 returned %08x\n", hr);
2814 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2815 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2816 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size 0 returned %08x\n", hr);
2817 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2819 desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2820 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2821 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2822 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2823 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2824 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2825 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2827 desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2828 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2829 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2830 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2831 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2832 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2833 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2835 IDirectDrawSurface7_Release(surface7);
2836 IDirectDrawSurface_Release(surface1);
2839 static void SurfaceCapsTest(void)
2841 DDSURFACEDESC create;
2844 IDirectDrawSurface *surface1 = NULL;
2845 DDSURFACEDESC2 create2, desc2;
2846 IDirectDrawSurface7 *surface7 = NULL;
2847 IDirectDraw7 *dd7 = NULL;
2848 DWORD create_caps[] = {
2849 DDSCAPS_OFFSCREENPLAIN,
2851 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD,
2853 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2854 DDSCAPS_PRIMARYSURFACE,
2855 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY,
2858 DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN
2860 DWORD expected_caps[] = {
2861 DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2862 DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2863 DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD,
2864 DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2865 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2866 DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_VISIBLE,
2867 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_VISIBLE,
2868 DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2869 DDSCAPS_ZBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY,
2870 DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM
2874 /* Tests various surface flags, what changes do they undergo during surface creation. Forsaken
2875 * engine expects texture surfaces without memory flag to get a video memory flag right after
2876 * creation. Currently, Wine adds DDSCAPS_FRONTBUFFER to primary surface, but native doesn't do this
2877 * for single buffered primaries. Because of this primary surface creation tests are todo_wine. No real
2878 * app is known so far to care about this. */
2880 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
2882 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
2886 for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2888 memset(&create, 0, sizeof(create));
2889 create.dwSize = sizeof(create);
2890 create.ddsCaps.dwCaps = create_caps[i];
2891 create.dwFlags = DDSD_CAPS;
2893 if (!(create.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2895 create.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2896 create.dwHeight = 128;
2897 create.dwWidth = 128;
2900 if (create.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
2902 create.dwFlags |= DDSD_PIXELFORMAT;
2903 create.ddpfPixelFormat.dwSize = sizeof(create.ddpfPixelFormat);
2904 create.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2905 U1(create.ddpfPixelFormat).dwZBufferBitDepth = 16;
2906 U3(create.ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
2909 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2910 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2914 memset(&desc, 0, sizeof(desc));
2915 desc.dwSize = sizeof(DDSURFACEDESC);
2916 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc);
2917 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2919 if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
2920 ok(desc.ddsCaps.dwCaps == expected_caps[i],
2921 "GetSurfaceDesc test %d returned caps %x, expected %x\n", i,
2922 desc.ddsCaps.dwCaps, expected_caps[i]);
2924 todo_wine ok(desc.ddsCaps.dwCaps == expected_caps[i],
2925 "GetSurfaceDesc test %d returned caps %x, expected %x\n", i,
2926 desc.ddsCaps.dwCaps, expected_caps[i]);
2928 IDirectDrawSurface_Release(surface1);
2932 /* Test for differences in ddraw 7 */
2933 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2934 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
2937 skip("Failed to get IDirectDraw7 interface, skipping tests\n");
2941 for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2943 memset(&create2, 0, sizeof(create2));
2944 create2.dwSize = sizeof(create2);
2945 create2.ddsCaps.dwCaps = create_caps[i];
2946 create2.dwFlags = DDSD_CAPS;
2948 if (!(create2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2950 create2.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2951 create2.dwHeight = 128;
2952 create2.dwWidth = 128;
2955 if (create2.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
2957 create2.dwFlags |= DDSD_PIXELFORMAT;
2958 U4(create2).ddpfPixelFormat.dwSize = sizeof(U4(create2).ddpfPixelFormat);
2959 U4(create2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2960 U1(U4(create2).ddpfPixelFormat).dwZBufferBitDepth = 16;
2961 U3(U4(create2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
2964 hr = IDirectDraw7_CreateSurface(dd7, &create2, &surface7, NULL);
2965 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2969 memset(&desc2, 0, sizeof(desc2));
2970 desc2.dwSize = sizeof(DDSURFACEDESC2);
2971 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc2);
2972 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2974 if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
2975 ok(desc2.ddsCaps.dwCaps == expected_caps[i],
2976 "GetSurfaceDesc test %d returned caps %x, expected %x\n", i,
2977 desc2.ddsCaps.dwCaps, expected_caps[i]);
2979 todo_wine ok(desc2.ddsCaps.dwCaps == expected_caps[i],
2980 "GetSurfaceDesc test %d returned caps %x, expected %x\n", i,
2981 desc2.ddsCaps.dwCaps, expected_caps[i]);
2983 IDirectDrawSurface7_Release(surface7);
2987 IDirectDraw7_Release(dd7);
2990 memset(&create, 0, sizeof(create));
2991 create.dwSize = sizeof(create);
2992 create.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2993 create.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY;
2994 create.dwWidth = 64;
2995 create.dwHeight = 64;
2996 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2997 ok(hr == DDERR_INVALIDCAPS, "Creating a SYSMEM | VIDMEM surface returned 0x%08x, expected DDERR_INVALIDCAPS\n", hr);
2998 if(surface1) IDirectDrawSurface_Release(surface1);
3001 static BOOL can_create_primary_surface(void)
3004 IDirectDrawSurface *surface;
3007 memset(&ddsd, 0, sizeof(ddsd));
3008 ddsd.dwSize = sizeof(ddsd);
3009 ddsd.dwFlags = DDSD_CAPS;
3010 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3011 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3012 if(FAILED(hr)) return FALSE;
3013 IDirectDrawSurface_Release(surface);
3017 static void dctest_surf(IDirectDrawSurface *surf, int ddsdver) {
3019 HDC dc, dc2 = (HDC) 0x1234;
3021 DDSURFACEDESC2 ddsd2;
3023 memset(&ddsd, 0, sizeof(ddsd));
3024 ddsd.dwSize = sizeof(ddsd);
3025 memset(&ddsd2, 0, sizeof(ddsd2));
3026 ddsd2.dwSize = sizeof(ddsd2);
3028 hr = IDirectDrawSurface_GetDC(surf, &dc);
3029 ok(hr == DD_OK, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
3031 hr = IDirectDrawSurface_GetDC(surf, &dc2);
3032 ok(hr == DDERR_DCALREADYCREATED, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
3033 ok(dc2 == (HDC) 0x1234, "The failed GetDC call changed the dc: %p\n", dc2);
3035 hr = IDirectDrawSurface_Lock(surf, NULL, ddsdver == 1 ? &ddsd : ((DDSURFACEDESC *) &ddsd2), 0, NULL);
3036 ok(hr == DDERR_SURFACEBUSY, "IDirectDrawSurface_Lock returned 0x%08x, expected DDERR_ALREADYLOCKED\n", hr);
3038 hr = IDirectDrawSurface_ReleaseDC(surf, dc);
3039 ok(hr == DD_OK, "IDirectDrawSurface_ReleaseDC failed: 0x%08x\n", hr);
3040 hr = IDirectDrawSurface_ReleaseDC(surf, dc);
3041 ok(hr == DDERR_NODC, "IDirectDrawSurface_ReleaseDC returned 0x%08x, expected DDERR_NODC\n", hr);
3044 static void GetDCTest(void)
3047 DDSURFACEDESC2 ddsd2;
3048 IDirectDrawSurface *surf;
3049 IDirectDrawSurface2 *surf2;
3050 IDirectDrawSurface4 *surf4;
3051 IDirectDrawSurface7 *surf7;
3052 IDirectDrawSurface *tmp;
3053 IDirectDrawSurface7 *tmp7;
3060 memset(&ddsd, 0, sizeof(ddsd));
3061 ddsd.dwSize = sizeof(ddsd);
3062 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3065 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3066 memset(&ddsd2, 0, sizeof(ddsd2));
3067 ddsd2.dwSize = sizeof(ddsd2);
3068 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3070 ddsd2.dwHeight = 64;
3071 ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3073 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
3074 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3075 dctest_surf(surf, 1);
3076 IDirectDrawSurface_Release(surf);
3078 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3079 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3081 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3082 ok(hr == DD_OK, "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
3083 dctest_surf(surf, 1);
3085 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
3086 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr);
3087 dctest_surf((IDirectDrawSurface *) surf2, 1);
3089 IDirectDrawSurface2_Release(surf2);
3090 IDirectDrawSurface_Release(surf);
3091 IDirectDraw2_Release(dd2);
3093 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3094 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3097 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3098 ok(hr == DD_OK, "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
3099 dctest_surf((IDirectDrawSurface *) surf4, 2);
3101 hr = IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)&surf);
3102 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3104 hr = IDirectDrawSurface4_GetDC(surf4, &dc);
3105 ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
3107 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, NULL);
3108 ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
3110 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
3111 ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
3112 ok(tmp == surf, "Expected surface %p, got %p.\n\n", surf, tmp);
3114 hr = IDirectDrawSurface4_ReleaseDC(surf4, dc);
3115 ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
3117 dc = CreateCompatibleDC(NULL);
3118 ok(!!dc, "CreateCompatibleDC failed.\n");
3120 tmp = (IDirectDrawSurface *)0xdeadbeef;
3121 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
3122 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3123 ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
3125 ok(DeleteDC(dc), "DeleteDC failed.\n");
3127 tmp = (IDirectDrawSurface *)0xdeadbeef;
3128 hr = IDirectDraw4_GetSurfaceFromDC(dd4, NULL, (IDirectDrawSurface4 **)&tmp);
3129 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3130 ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
3132 IDirectDrawSurface4_Release(surf4);
3133 IDirectDraw4_Release(dd4);
3135 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3136 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3138 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3139 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
3140 dctest_surf((IDirectDrawSurface *) surf7, 2);
3142 hr = IDirectDrawSurface7_GetDC(surf7, &dc);
3143 ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
3145 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, NULL);
3146 ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
3148 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
3149 ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
3150 ok(tmp7 == surf7, "Expected surface %p, got %p.\n\n", surf7, tmp7);
3151 IDirectDrawSurface7_Release(tmp7);
3153 hr = IDirectDrawSurface7_ReleaseDC(surf7, dc);
3154 ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
3156 dc = CreateCompatibleDC(NULL);
3157 ok(!!dc, "CreateCompatibleDC failed.\n");
3159 tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
3160 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
3161 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3162 ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
3164 ok(DeleteDC(dc), "DeleteDC failed.\n");
3166 tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
3167 hr = IDirectDraw7_GetSurfaceFromDC(dd7, NULL, (IDirectDrawSurface7 **)&tmp7);
3168 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3169 ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
3171 IDirectDrawSurface7_Release(surf7);
3172 IDirectDraw7_Release(dd7);
3175 static void GetDCFormatTest(void)
3177 DDSURFACEDESC2 ddsd;
3179 IDirectDrawSurface7 *surface;
3194 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3195 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
3202 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3203 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
3210 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3211 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
3214 DDERR_CANTCREATEDC /* Vista+ */
3219 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3220 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}
3223 DDERR_CANTCREATEDC /* Vista+ */
3228 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3229 {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}
3232 DDERR_CANTCREATEDC /* Vista+ */
3237 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3238 {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}
3241 DDERR_CANTCREATEDC /* Vista+ */
3246 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3247 {16}, {0x0000F800}, {0x000007E0}, {0x0000001F}, {0x00000000}
3254 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3255 {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00008000}
3262 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3263 {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00000000}
3270 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3271 { 8}, {0x000000E0}, {0x0000001C}, {0x00000003}, {0x00000000}
3276 /* Untested, windows test machine didn't support this format */
3277 "D3DFMT_A2R10G10B10",
3279 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3280 {32}, {0xC0000000}, {0x3FF00000}, {0x000FFC00}, {0x000003FF}
3285 * GetDC on a P8 surface fails unless the display mode is 8 bpp. This is not
3286 * implemented in wine yet, so disable the test for now. Succeeding P8 getDC
3287 * calls are tested in the ddraw.visual test.
3292 sizeof(DDPIXELFORMAT), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0,
3293 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3301 sizeof(DDPIXELFORMAT), DDPF_LUMINANCE, 0,
3302 {8 }, {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}
3309 sizeof(DDPIXELFORMAT), DDPF_ALPHAPIXELS | DDPF_LUMINANCE, 0,
3310 {16}, {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}
3317 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','1'),
3318 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3325 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','2'),
3326 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3333 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','3'),
3334 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3341 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','4'),
3342 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3349 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','5'),
3350 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3356 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3357 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed, hr = 0x%08x\n", hr);
3359 for(i = 0; i < (sizeof(testdata) / sizeof(testdata[0])); i++)
3361 memset(&ddsd, 0, sizeof(ddsd));
3362 ddsd.dwSize = sizeof(ddsd);
3363 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3366 U4(ddsd).ddpfPixelFormat = testdata[i].fmt;
3367 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3369 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3372 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
3373 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
3374 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3377 skip("IDirectDraw7_CreateSurface failed, hr = 0x%08x, format %s\n", hr, testdata[i].name);
3382 dc = (void *) 0x1234;
3383 hr = IDirectDrawSurface7_GetDC(surface, &dc);
3384 if(testdata[i].getdc_capable)
3387 (testdata[i].alt_result && hr == testdata[i].alt_result),
3388 "GetDC on a %s surface failed(0x%08x), expected it to work\n",
3389 testdata[i].name, hr);
3393 ok(FAILED(hr), "GetDC on a %s surface succeeded(0x%08x), expected it to fail\n",
3394 testdata[i].name, hr);
3399 IDirectDrawSurface7_ReleaseDC(surface, dc);
3400 ok(hr == DD_OK, "IDirectDrawSurface7_ReleaseDC failed, hr = 0x%08x\n", hr);
3405 ok(dc == NULL, "After failed GetDC dc is %p\n", dc);
3408 IDirectDrawSurface7_Release(surface);
3411 IDirectDraw7_Release(dd7);
3414 static void BackBufferCreateSurfaceTest(void)
3417 DDSURFACEDESC created_ddsd;
3418 DDSURFACEDESC2 ddsd2;
3419 IDirectDrawSurface *surf;
3420 IDirectDrawSurface4 *surf4;
3421 IDirectDrawSurface7 *surf7;
3427 const DWORD caps = DDSCAPS_BACKBUFFER;
3428 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3430 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3432 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3436 memset(&ddsd, 0, sizeof(ddsd));
3437 ddsd.dwSize = sizeof(ddsd);
3438 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3441 ddsd.ddsCaps.dwCaps = caps;
3442 memset(&ddsd2, 0, sizeof(ddsd2));
3443 ddsd2.dwSize = sizeof(ddsd2);
3444 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3446 ddsd2.dwHeight = 64;
3447 ddsd2.ddsCaps.dwCaps = caps;
3448 memset(&created_ddsd, 0, sizeof(created_ddsd));
3449 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3451 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
3452 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3455 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3456 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3457 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3458 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3460 IDirectDrawSurface_Release(surf);
3463 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3464 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3466 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3467 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3468 DDERR_INVALIDCAPS, hr);
3470 IDirectDraw2_Release(dd2);
3472 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3473 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3475 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3476 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3477 DDERR_INVALIDCAPS, hr);
3479 IDirectDraw4_Release(dd4);
3481 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3482 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3484 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3485 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3486 DDERR_INVALIDCAPS, hr);
3488 IDirectDraw7_Release(dd7);
3491 static void BackBufferAttachmentFlipTest(void)
3494 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3496 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3498 hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3499 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3501 /* Perform attachment tests on a back-buffer */
3502 memset(&ddsd, 0, sizeof(ddsd));
3503 ddsd.dwSize = sizeof(ddsd);
3504 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3505 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3506 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3507 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3508 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
3509 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3511 if (surface2 != NULL)
3513 /* Try a single primary and a two back buffers */
3514 memset(&ddsd, 0, sizeof(ddsd));
3515 ddsd.dwSize = sizeof(ddsd);
3516 ddsd.dwFlags = DDSD_CAPS;
3517 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3518 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
3519 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3521 memset(&ddsd, 0, sizeof(ddsd));
3522 ddsd.dwSize = sizeof(ddsd);
3523 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3524 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3525 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3526 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3527 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
3528 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3530 /* This one has a different size */
3531 memset(&ddsd, 0, sizeof(ddsd));
3532 ddsd.dwSize = sizeof(ddsd);
3533 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3534 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3536 ddsd.dwHeight = 128;
3537 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
3538 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3540 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3541 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3542 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3545 /* Try flipping the surfaces */
3546 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3547 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3548 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3549 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3551 /* Try the reverse without detaching first */
3552 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3553 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3554 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3555 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3557 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3558 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3559 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3562 /* Try flipping the surfaces */
3563 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3564 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3565 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3566 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3568 /* Try to detach reversed */
3569 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3570 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3571 /* Now the proper detach */
3572 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3573 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3575 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3576 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3577 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3580 /* Try flipping the surfaces */
3581 hr = IDirectDrawSurface_Flip(surface3, NULL, DDFLIP_WAIT);
3582 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3583 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3584 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3585 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3586 ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3588 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3589 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3591 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3592 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3593 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3594 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3596 IDirectDrawSurface_Release(surface4);
3597 IDirectDrawSurface_Release(surface3);
3598 IDirectDrawSurface_Release(surface2);
3599 IDirectDrawSurface_Release(surface1);
3602 hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
3603 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3605 DestroyWindow(window);
3608 static void CreateSurfaceBadCapsSizeTest(void)
3610 DDSURFACEDESC ddsd_ok;
3611 DDSURFACEDESC ddsd_bad1;
3612 DDSURFACEDESC ddsd_bad2;
3613 DDSURFACEDESC ddsd_bad3;
3614 DDSURFACEDESC ddsd_bad4;
3615 DDSURFACEDESC2 ddsd2_ok;
3616 DDSURFACEDESC2 ddsd2_bad1;
3617 DDSURFACEDESC2 ddsd2_bad2;
3618 DDSURFACEDESC2 ddsd2_bad3;
3619 DDSURFACEDESC2 ddsd2_bad4;
3620 IDirectDrawSurface *surf;
3621 IDirectDrawSurface4 *surf4;
3622 IDirectDrawSurface7 *surf7;
3628 const DWORD caps = DDSCAPS_OFFSCREENPLAIN;
3630 memset(&ddsd_ok, 0, sizeof(ddsd_ok));
3631 ddsd_ok.dwSize = sizeof(ddsd_ok);
3632 ddsd_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3633 ddsd_ok.dwWidth = 64;
3634 ddsd_ok.dwHeight = 64;
3635 ddsd_ok.ddsCaps.dwCaps = caps;
3636 memcpy(&ddsd_bad1, &ddsd_ok, sizeof(ddsd_bad1));
3638 memcpy(&ddsd_bad2, &ddsd_ok, sizeof(ddsd_bad2));
3640 memcpy(&ddsd_bad3, &ddsd_ok, sizeof(ddsd_bad3));
3641 ddsd_bad3.dwSize = 0;
3642 memcpy(&ddsd_bad4, &ddsd_ok, sizeof(ddsd_bad4));
3643 ddsd_bad4.dwSize = sizeof(DDSURFACEDESC2);
3645 memset(&ddsd2_ok, 0, sizeof(ddsd2_ok));
3646 ddsd2_ok.dwSize = sizeof(ddsd2_ok);
3647 ddsd2_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3648 ddsd2_ok.dwWidth = 64;
3649 ddsd2_ok.dwHeight = 64;
3650 ddsd2_ok.ddsCaps.dwCaps = caps;
3651 memcpy(&ddsd2_bad1, &ddsd2_ok, sizeof(ddsd2_bad1));
3652 ddsd2_bad1.dwSize--;
3653 memcpy(&ddsd2_bad2, &ddsd2_ok, sizeof(ddsd2_bad2));
3654 ddsd2_bad2.dwSize++;
3655 memcpy(&ddsd2_bad3, &ddsd2_ok, sizeof(ddsd2_bad3));
3656 ddsd2_bad3.dwSize = 0;
3657 memcpy(&ddsd2_bad4, &ddsd2_ok, sizeof(ddsd2_bad4));
3658 ddsd2_bad4.dwSize = sizeof(DDSURFACEDESC);
3660 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_ok, &surf, NULL);
3661 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3662 IDirectDrawSurface_Release(surf);
3664 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad1, &surf, NULL);
3665 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3666 DDERR_INVALIDPARAMS, hr);
3667 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad2, &surf, NULL);
3668 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3669 DDERR_INVALIDPARAMS, hr);
3670 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad3, &surf, NULL);
3671 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3672 DDERR_INVALIDPARAMS, hr);
3673 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad4, &surf, NULL);
3674 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3675 DDERR_INVALIDPARAMS, hr);
3676 hr = IDirectDraw_CreateSurface(lpDD, NULL, &surf, NULL);
3677 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3678 DDERR_INVALIDPARAMS, hr);
3680 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3681 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3683 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_ok, &surf, NULL);
3684 ok(SUCCEEDED(hr), "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
3685 IDirectDrawSurface_Release(surf);
3687 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad1, &surf, NULL);
3688 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3689 DDERR_INVALIDPARAMS, hr);
3690 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad2, &surf, NULL);
3691 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3692 DDERR_INVALIDPARAMS, hr);
3693 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad3, &surf, NULL);
3694 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3695 DDERR_INVALIDPARAMS, hr);
3696 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad4, &surf, NULL);
3697 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3698 DDERR_INVALIDPARAMS, hr);
3699 hr = IDirectDraw2_CreateSurface(dd2, NULL, &surf, NULL);
3700 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3701 DDERR_INVALIDPARAMS, hr);
3703 IDirectDraw2_Release(dd2);
3705 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3706 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3708 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_ok, &surf4, NULL);
3709 ok(SUCCEEDED(hr), "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
3710 IDirectDrawSurface4_Release(surf4);
3712 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad1, &surf4, NULL);
3713 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3714 DDERR_INVALIDPARAMS, hr);
3715 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad2, &surf4, NULL);
3716 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3717 DDERR_INVALIDPARAMS, hr);
3718 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad3, &surf4, NULL);
3719 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3720 DDERR_INVALIDPARAMS, hr);
3721 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad4, &surf4, NULL);
3722 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3723 DDERR_INVALIDPARAMS, hr);
3724 hr = IDirectDraw4_CreateSurface(dd4, NULL, &surf4, NULL);
3725 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3726 DDERR_INVALIDPARAMS, hr);
3728 IDirectDraw4_Release(dd4);
3730 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3731 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3733 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_ok, &surf7, NULL);
3734 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
3735 IDirectDrawSurface7_Release(surf7);
3737 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad1, &surf7, NULL);
3738 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3739 DDERR_INVALIDPARAMS, hr);
3740 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad2, &surf7, NULL);
3741 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3742 DDERR_INVALIDPARAMS, hr);
3743 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad3, &surf7, NULL);
3744 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3745 DDERR_INVALIDPARAMS, hr);
3746 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad4, &surf7, NULL);
3747 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3748 DDERR_INVALIDPARAMS, hr);
3749 hr = IDirectDraw7_CreateSurface(dd7, NULL, &surf7, NULL);
3750 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3751 DDERR_INVALIDPARAMS, hr);
3753 IDirectDraw7_Release(dd7);
3756 START_TEST(dsurface)
3761 if (!CreateDirectDraw())
3764 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3765 if (ret == E_NOINTERFACE)
3767 win_skip("DirectDraw4 and higher are not supported\n");
3768 ReleaseDirectDraw();
3771 IDirectDraw_Release(dd4);
3773 if(!can_create_primary_surface())
3775 skip("Unable to create primary surface\n");
3779 ddcaps.dwSize = sizeof(DDCAPS);
3780 ret = IDirectDraw_GetCaps(lpDD, &ddcaps, NULL);
3783 skip("IDirectDraw_GetCaps failed with %08x\n", ret);
3787 MipMapCreationTest();
3788 SrcColorKey32BlitTest();
3799 test_lockrect_invalid();
3809 BackBufferCreateSurfaceTest();
3810 BackBufferAttachmentFlipTest();
3811 CreateSurfaceBadCapsSizeTest();
3812 ReleaseDirectDraw();