d3d10core: Implement d3d10_device_OMGetRenderTargets().
[wine.git] / dlls / ddraw / tests / dsurface.c
blobfe5b67600bb58ef312a133d7795f290dbccb14c8
1 /*
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-2009, 2011 Stefan Dösinger for CodeWeavers
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
24 #define COBJMACROS
26 #include "wine/test.h"
27 #include "wine/exception.h"
28 #include "ddraw.h"
29 #include "d3d.h"
30 #include "unknwn.h"
32 static HRESULT (WINAPI *pDirectDrawCreateEx)(GUID *, void **, REFIID, IUnknown *);
34 static IDirectDraw *lpDD;
35 static DDCAPS ddcaps;
37 static BOOL CreateDirectDraw(void)
39 HRESULT rc;
41 rc = DirectDrawCreate(NULL, &lpDD, NULL);
42 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
43 if (!lpDD) {
44 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
45 return FALSE;
48 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
49 ok(rc==DD_OK,"SetCooperativeLevel returned: %x\n",rc);
51 return TRUE;
55 static void ReleaseDirectDraw(void)
57 if( lpDD != NULL )
59 IDirectDraw_Release(lpDD);
60 lpDD = NULL;
64 static void MipMapCreationTest(void)
66 IDirectDrawSurface *lpDDSMipMapTest;
67 DDSURFACEDESC ddsd;
68 HRESULT rc;
70 /* First mipmap creation test: create a surface with DDSCAPS_COMPLEX,
71 DDSCAPS_MIPMAP, and DDSD_MIPMAPCOUNT. This create the number of
72 requested mipmap levels. */
73 ddsd.dwSize = sizeof(ddsd);
74 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
75 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
76 U2(ddsd).dwMipMapCount = 3;
77 ddsd.dwWidth = 128;
78 ddsd.dwHeight = 32;
79 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
80 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
81 if (FAILED(rc))
83 skip("failed to create surface\n");
84 return;
87 /* Check the number of created mipmaps */
88 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
89 ddsd.dwSize = sizeof(ddsd);
90 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
91 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
92 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
93 "GetSurfaceDesc returned no mipmapcount.\n");
94 ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %d.\n",
95 U2(ddsd).dwMipMapCount);
97 /* Destroy the surface. */
98 IDirectDrawSurface_Release(lpDDSMipMapTest);
101 /* Second mipmap creation test: create a surface without a mipmap
102 count, with DDSCAPS_MIPMAP and without DDSCAPS_COMPLEX.
103 This creates a single mipmap level. */
104 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
105 ddsd.dwSize = sizeof(ddsd);
106 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
107 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
108 ddsd.dwWidth = 128;
109 ddsd.dwHeight = 32;
110 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
111 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
112 if (FAILED(rc))
114 skip("failed to create surface\n");
115 return;
117 /* Check the number of created mipmaps */
118 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
119 ddsd.dwSize = sizeof(ddsd);
120 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
121 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
122 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
123 "GetSurfaceDesc returned no mipmapcount.\n");
124 ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %d.\n",
125 U2(ddsd).dwMipMapCount);
127 /* Destroy the surface. */
128 IDirectDrawSurface_Release(lpDDSMipMapTest);
131 /* Third mipmap creation test: create a surface with DDSCAPS_MIPMAP,
132 DDSCAPS_COMPLEX and without DDSD_MIPMAPCOUNT.
133 It's an undocumented features where a chain of mipmaps, starting from
134 he specified size and down to the smallest size, is automatically
135 created.
136 Anarchy Online needs this feature to work. */
137 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
138 ddsd.dwSize = sizeof(ddsd);
139 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
140 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
141 ddsd.dwWidth = 128;
142 ddsd.dwHeight = 32;
143 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
144 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
145 if (FAILED(rc))
147 skip("failed to create surface\n");
148 return;
151 /* Check the number of created mipmaps */
152 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
153 ddsd.dwSize = sizeof(ddsd);
154 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
155 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
156 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
157 "GetSurfaceDesc returned no mipmapcount.\n");
158 ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
159 U2(ddsd).dwMipMapCount);
161 /* Destroy the surface. */
162 IDirectDrawSurface_Release(lpDDSMipMapTest);
165 /* Fourth mipmap creation test: same as above with a different texture
166 size.
167 The purpose is to verify that the number of generated mipmaps is
168 dependent on the smallest dimension. */
169 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
170 ddsd.dwSize = sizeof(ddsd);
171 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
172 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
173 ddsd.dwWidth = 32;
174 ddsd.dwHeight = 64;
175 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
176 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
177 if (FAILED(rc))
179 skip("failed to create surface\n");
180 return;
183 /* Check the number of created mipmaps */
184 memset(&ddsd, 0, sizeof(DDSURFACEDESC));
185 ddsd.dwSize = sizeof(ddsd);
186 rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
187 ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
188 ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
189 "GetSurfaceDesc returned no mipmapcount.\n");
190 ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
191 U2(ddsd).dwMipMapCount);
193 /* Destroy the surface. */
194 IDirectDrawSurface_Release(lpDDSMipMapTest);
197 /* Fifth mipmap creation test: try to create a surface with
198 DDSCAPS_COMPLEX, DDSCAPS_MIPMAP, DDSD_MIPMAPCOUNT,
199 where dwMipMapCount = 0. This should fail. */
201 ddsd.dwSize = sizeof(ddsd);
202 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
203 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
204 U2(ddsd).dwMipMapCount = 0;
205 ddsd.dwWidth = 128;
206 ddsd.dwHeight = 32;
207 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
208 ok(rc==DDERR_INVALIDPARAMS,"CreateSurface returned: %x\n",rc);
210 /* Destroy the surface. */
211 if( rc == DD_OK )
212 IDirectDrawSurface_Release(lpDDSMipMapTest);
216 static void SrcColorKey32BlitTest(void)
218 IDirectDrawSurface *lpSrc;
219 IDirectDrawSurface *lpDst;
220 DDSURFACEDESC ddsd, ddsd2;
221 DDCOLORKEY DDColorKey;
222 LPDWORD lpData;
223 HRESULT rc;
224 DDBLTFX fx;
226 ddsd2.dwSize = sizeof(ddsd2);
227 ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
229 ddsd.dwSize = sizeof(ddsd);
230 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
231 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
232 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
233 ddsd.dwWidth = 800;
234 ddsd.dwHeight = 600;
235 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
236 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
237 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
238 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
239 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
240 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
241 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
242 if (FAILED(rc))
244 skip("failed to create surface\n");
245 return;
248 ddsd.dwFlags |= DDSD_CKSRCBLT;
249 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
250 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
251 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
252 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
253 if (FAILED(rc))
255 skip("failed to create surface\n");
256 return;
259 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
260 ok(rc==DD_OK,"Lock returned: %x\n",rc);
261 lpData = ddsd2.lpSurface;
262 lpData[0] = 0xCCCCCCCC;
263 lpData[1] = 0xCCCCCCCC;
264 lpData[2] = 0xCCCCCCCC;
265 lpData[3] = 0xCCCCCCCC;
267 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
268 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
270 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
271 ok(rc==DD_OK,"Lock returned: %x\n",rc);
272 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
273 lpData = ddsd2.lpSurface;
274 lpData[0] = 0x77010203;
275 lpData[1] = 0x00010203;
276 lpData[2] = 0x77FF00FF;
277 lpData[3] = 0x00FF00FF;
278 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
279 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
281 IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
283 rc = IDirectDrawSurface_Lock(lpDst, 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 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
288 * color keying, but copy it to the destination surface. Others apply it for color keying, but
289 * do not copy it into the destination surface.
291 if(lpData[0]==0x00010203) {
292 trace("X channel was not copied into the destination surface\n");
293 ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
294 "Destination data after blitting is not correct\n");
295 } else {
296 ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
297 "Destination data after blitting is not correct\n");
299 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
300 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
302 /* Below we repeat the same test as above but now using BltFast instead of Blt. Before
303 * we can carry out the test we need to restore the color of the destination surface.
305 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
306 ok(rc==DD_OK,"Lock returned: %x\n",rc);
307 lpData = ddsd2.lpSurface;
308 lpData[0] = 0xCCCCCCCC;
309 lpData[1] = 0xCCCCCCCC;
310 lpData[2] = 0xCCCCCCCC;
311 lpData[3] = 0xCCCCCCCC;
312 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
313 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
315 IDirectDrawSurface_BltFast(lpDst, 0, 0, lpSrc, NULL, DDBLTFAST_SRCCOLORKEY);
317 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
318 ok(rc==DD_OK,"Lock returned: %x\n",rc);
319 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
320 lpData = ddsd2.lpSurface;
321 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
322 * color keying, but copy it to the destination surface. Others apply it for color keying, but
323 * do not copy it into the destination surface.
325 if(lpData[0]==0x00010203) {
326 trace("X channel was not copied into the destination surface\n");
327 ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
328 "Destination data after blitting is not correct\n");
329 } else {
330 ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
331 "Destination data after blitting is not correct\n");
333 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
334 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
336 /* Also test SetColorKey */
337 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
338 ok(DDColorKey.dwColorSpaceLowValue == 0xFF00FF && DDColorKey.dwColorSpaceHighValue == 0xFF00FF,
339 "GetColorKey does not return the colorkey used at surface creation\n");
341 DDColorKey.dwColorSpaceLowValue = 0x00FF00;
342 DDColorKey.dwColorSpaceHighValue = 0x00FF00;
343 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
345 DDColorKey.dwColorSpaceLowValue = 0;
346 DDColorKey.dwColorSpaceHighValue = 0;
347 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
348 ok(DDColorKey.dwColorSpaceLowValue == 0x00FF00 && DDColorKey.dwColorSpaceHighValue == 0x00FF00,
349 "GetColorKey does not return the colorkey set with SetColorKey\n");
351 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
352 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
353 IDirectDrawSurface_GetSurfaceDesc(lpSrc, &ddsd);
354 ok(ddsd.ddckCKSrcBlt.dwColorSpaceLowValue == 0x00FF00 && ddsd.ddckCKSrcBlt.dwColorSpaceHighValue == 0x00FF00,
355 "GetSurfaceDesc does not return the colorkey set with SetColorKey\n");
357 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
358 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
359 DDColorKey.dwColorSpaceHighValue = 0x000000;
360 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
362 DDColorKey.dwColorSpaceLowValue = 0;
363 DDColorKey.dwColorSpaceHighValue = 0;
364 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
365 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
366 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
368 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
369 DDColorKey.dwColorSpaceHighValue = 0x000001;
370 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
372 DDColorKey.dwColorSpaceLowValue = 0;
373 DDColorKey.dwColorSpaceHighValue = 0;
374 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
375 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
376 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
378 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
379 DDColorKey.dwColorSpaceHighValue = 0x0000FE;
380 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
382 DDColorKey.dwColorSpaceLowValue = 0;
383 DDColorKey.dwColorSpaceHighValue = 0;
384 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
385 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
386 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
388 IDirectDrawSurface_Release(lpSrc);
389 IDirectDrawSurface_Release(lpDst);
391 /* start with a new set of surfaces to test the color keying parameters to blit */
392 memset(&ddsd, 0, sizeof(ddsd));
393 ddsd.dwSize = sizeof(ddsd);
394 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
395 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
396 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
397 ddsd.dwWidth = 800;
398 ddsd.dwHeight = 600;
399 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
400 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
401 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
402 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
403 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
404 ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0xFF0000;
405 ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0xFF0000;
406 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x00FF00;
407 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x00FF00;
408 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
409 ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
410 if(FAILED(rc))
412 skip("Failed to create surface\n");
413 return;
416 /* start with a new set of surfaces to test the color keying parameters to blit */
417 memset(&ddsd, 0, sizeof(ddsd));
418 ddsd.dwSize = sizeof(ddsd);
419 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
420 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
421 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
422 ddsd.dwWidth = 800;
423 ddsd.dwHeight = 600;
424 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
425 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
426 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
427 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
428 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
429 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x0000FF;
430 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x0000FF;
431 ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0x000000;
432 ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0x000000;
433 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
434 ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
435 if(FAILED(rc))
437 skip("Failed to create surface\n");
438 IDirectDrawSurface_Release(lpDst);
439 return;
442 memset(&fx, 0, sizeof(fx));
443 fx.dwSize = sizeof(fx);
444 fx.ddckSrcColorkey.dwColorSpaceHighValue = 0x110000;
445 fx.ddckSrcColorkey.dwColorSpaceLowValue = 0x110000;
446 fx.ddckDestColorkey.dwColorSpaceHighValue = 0x001100;
447 fx.ddckDestColorkey.dwColorSpaceLowValue = 0x001100;
449 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
450 ok(rc==DD_OK,"Lock returned: %x\n",rc);
451 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
452 lpData = ddsd2.lpSurface;
453 lpData[0] = 0x000000FF; /* Applies to src blt key in src surface */
454 lpData[1] = 0x00000000; /* Applies to dst blt key in src surface */
455 lpData[2] = 0x00FF0000; /* Dst color key in dst surface */
456 lpData[3] = 0x0000FF00; /* Src color key in dst surface */
457 lpData[4] = 0x00001100; /* Src color key in ddbltfx */
458 lpData[5] = 0x00110000; /* Dst color key in ddbltfx */
459 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
460 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
462 rc = IDirectDrawSurface_Lock(lpDst, 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] = 0x55555555;
467 lpData[1] = 0x55555555;
468 lpData[2] = 0x55555555;
469 lpData[3] = 0x55555555;
470 lpData[4] = 0x55555555;
471 lpData[5] = 0x55555555;
472 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
473 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
475 /* Test a blit without keying */
476 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, 0, &fx);
477 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
479 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
480 ok(rc==DD_OK,"Lock returned: %x\n",rc);
481 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
482 lpData = ddsd2.lpSurface;
483 /* Should have copied src data unmodified to dst */
484 ok(lpData[0] == 0x000000FF &&
485 lpData[1] == 0x00000000 &&
486 lpData[2] == 0x00FF0000 &&
487 lpData[3] == 0x0000FF00 &&
488 lpData[4] == 0x00001100 &&
489 lpData[5] == 0x00110000, "Surface data after unkeyed blit does not match\n");
491 lpData[0] = 0x55555555;
492 lpData[1] = 0x55555555;
493 lpData[2] = 0x55555555;
494 lpData[3] = 0x55555555;
495 lpData[4] = 0x55555555;
496 lpData[5] = 0x55555555;
497 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
498 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
500 /* Src key */
501 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
502 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
504 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
505 ok(rc==DD_OK,"Lock returned: %x\n",rc);
506 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
507 lpData = ddsd2.lpSurface;
509 ok(lpData[0] == 0x55555555 && /* Here the src key applied */
510 lpData[1] == 0x00000000 &&
511 lpData[2] == 0x00FF0000 &&
512 lpData[3] == 0x0000FF00 &&
513 lpData[4] == 0x00001100 &&
514 lpData[5] == 0x00110000, "Surface data after srckey blit does not match\n");
516 lpData[0] = 0x55555555;
517 lpData[1] = 0x55555555;
518 lpData[2] = 0x55555555;
519 lpData[3] = 0x55555555;
520 lpData[4] = 0x55555555;
521 lpData[5] = 0x55555555;
522 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
523 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
525 /* Src override */
526 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
527 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
529 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
530 ok(rc==DD_OK,"Lock returned: %x\n",rc);
531 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
532 lpData = ddsd2.lpSurface;
534 ok(lpData[0] == 0x000000FF &&
535 lpData[1] == 0x00000000 &&
536 lpData[2] == 0x00FF0000 &&
537 lpData[3] == 0x0000FF00 &&
538 lpData[4] == 0x00001100 &&
539 lpData[5] == 0x55555555, /* Override key applies here */
540 "Surface data after src override key blit does not match\n");
542 lpData[0] = 0x55555555;
543 lpData[1] = 0x55555555;
544 lpData[2] = 0x55555555;
545 lpData[3] = 0x55555555;
546 lpData[4] = 0x55555555;
547 lpData[5] = 0x55555555;
548 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
549 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
551 /* Src override AND src key. That is not supposed to work */
552 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &fx);
553 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
555 /* Verify that the destination is unchanged */
556 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
557 ok(rc==DD_OK,"Lock returned: %x\n",rc);
558 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
559 lpData = ddsd2.lpSurface;
561 ok(lpData[0] == 0x55555555 &&
562 lpData[1] == 0x55555555 &&
563 lpData[2] == 0x55555555 &&
564 lpData[3] == 0x55555555 &&
565 lpData[4] == 0x55555555 &&
566 lpData[5] == 0x55555555, /* Override key applies here */
567 "Surface data after src key blit with override does not match\n");
569 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
570 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
571 lpData[2] = 0x00001100; /* Dest key in override */
572 lpData[3] = 0x00001100; /* Dest key in override */
573 lpData[4] = 0x00000000; /* Dest key in src surface */
574 lpData[5] = 0x00000000; /* Dest key in src surface */
575 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
576 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
578 /* Dest key blit */
579 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
580 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
582 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
583 ok(rc==DD_OK,"Lock returned: %x\n",rc);
584 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
585 lpData = ddsd2.lpSurface;
587 /* DirectDraw uses the dest blit key from the SOURCE surface ! */
588 ok(lpData[0] == 0x00ff0000 &&
589 lpData[1] == 0x00ff0000 &&
590 lpData[2] == 0x00001100 &&
591 lpData[3] == 0x00001100 &&
592 lpData[4] == 0x00001100 && /* Key applies here */
593 lpData[5] == 0x00110000, /* Key applies here */
594 "Surface data after dest key blit does not match\n");
596 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
597 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
598 lpData[2] = 0x00001100; /* Dest key in override */
599 lpData[3] = 0x00001100; /* Dest key in override */
600 lpData[4] = 0x00000000; /* Dest key in src surface */
601 lpData[5] = 0x00000000; /* Dest key in src surface */
602 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
603 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
605 /* Dest override key blit */
606 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
607 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
609 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
610 ok(rc==DD_OK,"Lock returned: %x\n",rc);
611 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
612 lpData = ddsd2.lpSurface;
614 ok(lpData[0] == 0x00FF0000 &&
615 lpData[1] == 0x00FF0000 &&
616 lpData[2] == 0x00FF0000 && /* Key applies here */
617 lpData[3] == 0x0000FF00 && /* Key applies here */
618 lpData[4] == 0x00000000 &&
619 lpData[5] == 0x00000000,
620 "Surface data after dest key override blit does not match\n");
622 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
623 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
624 lpData[2] = 0x00001100; /* Dest key in override */
625 lpData[3] = 0x00001100; /* Dest key in override */
626 lpData[4] = 0x00000000; /* Dest key in src surface */
627 lpData[5] = 0x00000000; /* Dest key in src surface */
628 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
629 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
631 /* Dest override key blit. Supposed to fail too */
632 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYDESTOVERRIDE, &fx);
633 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
635 /* Check for unchanged data */
636 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
637 ok(rc==DD_OK,"Lock returned: %x\n",rc);
638 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
639 lpData = ddsd2.lpSurface;
641 ok(lpData[0] == 0x00FF0000 &&
642 lpData[1] == 0x00FF0000 &&
643 lpData[2] == 0x00001100 && /* Key applies here */
644 lpData[3] == 0x00001100 && /* Key applies here */
645 lpData[4] == 0x00000000 &&
646 lpData[5] == 0x00000000,
647 "Surface data with dest key and dest override does not match\n");
649 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
650 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
651 lpData[2] = 0x00001100; /* Dest key in override */
652 lpData[3] = 0x00001100; /* Dest key in override */
653 lpData[4] = 0x00000000; /* Dest key in src surface */
654 lpData[5] = 0x00000000; /* Dest key in src surface */
655 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
656 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
658 /* Modify the source data a bit to give some more conclusive results */
659 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
660 ok(rc==DD_OK,"Lock returned: %x\n",rc);
661 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
662 lpData = ddsd2.lpSurface;
663 lpData[5] = 0x000000FF; /* Applies to src blt key in src surface */
664 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
665 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
667 /* Source and destination key */
668 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYSRC, &fx);
669 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
671 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
672 ok(rc==DD_OK,"Lock returned: %x\n",rc);
673 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
674 lpData = ddsd2.lpSurface;
676 ok(lpData[0] == 0x00FF0000 && /* Masked by Destination key */
677 lpData[1] == 0x00FF0000 && /* Masked by Destination key */
678 lpData[2] == 0x00001100 && /* Masked by Destination key */
679 lpData[3] == 0x00001100 && /* Masked by Destination key */
680 lpData[4] == 0x00001100 && /* Allowed by destination key, not masked by source key */
681 lpData[5] == 0x00000000, /* Allowed by dst key, but masked by source key */
682 "Surface data with src key and dest key blit does not match\n");
684 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
685 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
686 lpData[2] = 0x00001100; /* Dest key in override */
687 lpData[3] = 0x00001100; /* Dest key in override */
688 lpData[4] = 0x00000000; /* Dest key in src surface */
689 lpData[5] = 0x00000000; /* Dest key in src surface */
690 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
691 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
693 /* Override keys without ddbltfx parameter fail */
694 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, NULL);
695 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
696 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, NULL);
697 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
699 /* Try blitting without keys in the source surface*/
700 rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, NULL);
701 ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
702 rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_DESTBLT, NULL);
703 ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
705 /* That fails now. Do not bother to check that the data is unmodified */
706 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
707 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
709 /* Dest key blit still works. Which key is used this time??? */
710 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
711 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
713 /* With correctly passed override keys no key in the surface is needed.
714 * Again, the result was checked before, no need to do that again
716 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
717 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
718 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
719 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
721 IDirectDrawSurface_Release(lpSrc);
722 IDirectDrawSurface_Release(lpDst);
725 static void QueryInterface(void)
727 IDirectDrawSurface *dsurface;
728 DDSURFACEDESC surface;
729 void *object;
730 HRESULT ret;
732 /* Create a surface */
733 ZeroMemory(&surface, sizeof(surface));
734 surface.dwSize = sizeof(surface);
735 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
736 surface.dwHeight = 10;
737 surface.dwWidth = 10;
738 ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
739 if(ret != DD_OK)
741 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
742 return;
745 /* Call IUnknown::QueryInterface */
746 ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
747 ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %x\n", ret);
749 IDirectDrawSurface_Release(dsurface);
752 /* The following tests test which interface is returned by IDirectDrawSurfaceX::GetDDInterface.
753 * It uses refcounts to test that and compares the interface addresses. Partially fits here, and
754 * partially in the refcount test
757 static ULONG getref(IUnknown *iface)
759 IUnknown_AddRef(iface);
760 return IUnknown_Release(iface);
763 static void GetDDInterface_1(void)
765 IDirectDrawSurface2 *dsurface2;
766 IDirectDrawSurface *dsurface;
767 DDSURFACEDESC surface;
768 HRESULT ret;
769 IDirectDraw2 *dd2;
770 IDirectDraw4 *dd4;
771 IDirectDraw7 *dd7;
772 ULONG ref1, ref2, ref4, ref7;
773 void *dd;
775 /* Create a surface */
776 ZeroMemory(&surface, sizeof(surface));
777 surface.dwSize = sizeof(surface);
778 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
779 surface.dwHeight = 10;
780 surface.dwWidth = 10;
781 ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
782 if(ret != DD_OK)
784 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
785 return;
787 ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
788 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
789 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
790 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
791 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
792 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
793 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
794 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
796 ref1 = getref((IUnknown *) lpDD);
797 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
798 ref2 = getref((IUnknown *) dd2);
799 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
800 ref4 = getref((IUnknown *) dd4);
801 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
802 ref7 = getref((IUnknown *) dd7);
803 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
806 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
807 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
808 ok(getref((IUnknown *) lpDD) == ref1 + 1, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
809 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
810 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
811 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
813 ok(dd == lpDD, "Returned interface pointer is not equal to the creation interface\n");
814 IUnknown_Release((IUnknown *) dd);
816 /* try a NULL pointer */
817 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, NULL);
818 ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
820 IDirectDraw_Release(dd2);
821 IDirectDraw_Release(dd4);
822 IDirectDraw_Release(dd7);
823 IDirectDrawSurface2_Release(dsurface2);
824 IDirectDrawSurface_Release(dsurface);
827 static void GetDDInterface_2(void)
829 IDirectDrawSurface2 *dsurface2;
830 IDirectDrawSurface *dsurface;
831 DDSURFACEDESC surface;
832 HRESULT ret;
833 IDirectDraw2 *dd2;
834 IDirectDraw4 *dd4;
835 IDirectDraw7 *dd7;
836 ULONG ref1, ref2, ref4, ref7;
837 void *dd;
839 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
840 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
841 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
842 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
843 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
844 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
846 /* Create a surface */
847 ZeroMemory(&surface, sizeof(surface));
848 surface.dwSize = sizeof(surface);
849 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
850 surface.dwHeight = 10;
851 surface.dwWidth = 10;
852 ret = IDirectDraw2_CreateSurface(dd2, &surface, &dsurface, NULL);
853 if(ret != DD_OK)
855 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
856 return;
858 ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
859 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
861 ref1 = getref((IUnknown *) lpDD);
862 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
863 ref2 = getref((IUnknown *) dd2);
864 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
865 ref4 = getref((IUnknown *) dd4);
866 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
867 ref7 = getref((IUnknown *) dd7);
868 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
871 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
872 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
873 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
874 ok(getref((IUnknown *) dd2) == ref2 + 1, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
875 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
876 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
878 ok(dd == dd2, "Returned interface pointer is not equal to the creation interface\n");
879 IUnknown_Release((IUnknown *) dd);
881 IDirectDraw_Release(dd2);
882 IDirectDraw_Release(dd4);
883 IDirectDraw_Release(dd7);
884 IDirectDrawSurface2_Release(dsurface2);
885 IDirectDrawSurface_Release(dsurface);
888 static void GetDDInterface_4(void)
890 IDirectDrawSurface4 *dsurface4;
891 IDirectDrawSurface2 *dsurface2;
892 DDSURFACEDESC2 surface;
893 HRESULT ret;
894 IDirectDraw2 *dd2;
895 IDirectDraw4 *dd4;
896 IDirectDraw7 *dd7;
897 ULONG ref1, ref2, ref4, ref7;
898 void *dd;
900 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
901 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
902 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
903 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
904 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
905 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
907 /* Create a surface */
908 ZeroMemory(&surface, sizeof(surface));
909 surface.dwSize = sizeof(surface);
910 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
911 surface.dwHeight = 10;
912 surface.dwWidth = 10;
913 ret = IDirectDraw4_CreateSurface(dd4, &surface, &dsurface4, NULL);
914 if(ret != DD_OK)
916 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
917 return;
919 ret = IDirectDrawSurface4_QueryInterface(dsurface4, &IID_IDirectDrawSurface2, (void **) &dsurface2);
920 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
922 ref1 = getref((IUnknown *) lpDD);
923 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
924 ref2 = getref((IUnknown *) dd2);
925 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
926 ref4 = getref((IUnknown *) dd4);
927 ok(ref4 == 2, "IDirectDraw4 refcount is %d\n", ref4);
928 ref7 = getref((IUnknown *) dd7);
929 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
931 ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
932 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
933 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
934 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
935 ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
936 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
938 ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
939 IUnknown_Release((IUnknown *) dd);
941 /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
942 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
943 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
944 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
945 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
946 ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
947 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
949 ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
950 IUnknown_Release((IUnknown *) dd);
952 IDirectDraw_Release(dd2);
953 IDirectDraw_Release(dd4);
954 IDirectDraw_Release(dd7);
955 IDirectDrawSurface4_Release(dsurface4);
956 IDirectDrawSurface2_Release(dsurface2);
959 static void GetDDInterface_7(void)
961 IDirectDrawSurface7 *dsurface7;
962 IDirectDrawSurface4 *dsurface4;
963 DDSURFACEDESC2 surface;
964 HRESULT ret;
965 IDirectDraw2 *dd2;
966 IDirectDraw4 *dd4;
967 IDirectDraw7 *dd7;
968 ULONG ref1, ref2, ref4, ref7;
969 void *dd;
971 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
972 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
973 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
974 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
975 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
976 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
978 /* Create a surface */
979 ZeroMemory(&surface, sizeof(surface));
980 surface.dwSize = sizeof(surface);
981 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
982 surface.dwHeight = 10;
983 surface.dwWidth = 10;
984 ret = IDirectDraw7_CreateSurface(dd7, &surface, &dsurface7, NULL);
985 if(ret != DD_OK)
987 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
988 return;
990 ret = IDirectDrawSurface7_QueryInterface(dsurface7, &IID_IDirectDrawSurface4, (void **) &dsurface4);
991 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
993 ref1 = getref((IUnknown *) lpDD);
994 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
995 ref2 = getref((IUnknown *) dd2);
996 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
997 ref4 = getref((IUnknown *) dd4);
998 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
999 ref7 = getref((IUnknown *) dd7);
1000 ok(ref7 == 2, "IDirectDraw7 refcount is %d\n", ref7);
1002 ret = IDirectDrawSurface7_GetDDInterface(dsurface7, &dd);
1003 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1004 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1005 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1006 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1007 ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1009 ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1010 IUnknown_Release((IUnknown *) dd);
1012 /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
1013 ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
1014 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1015 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1016 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1017 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1018 ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1020 ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1021 IUnknown_Release((IUnknown *) dd);
1023 IDirectDraw_Release(dd2);
1024 IDirectDraw_Release(dd4);
1025 IDirectDraw_Release(dd7);
1026 IDirectDrawSurface4_Release(dsurface4);
1027 IDirectDrawSurface7_Release(dsurface7);
1030 static ULONG getRefcount(IUnknown *iface)
1032 IUnknown_AddRef(iface);
1033 return IUnknown_Release(iface);
1036 #define MAXEXPECTED 8 /* Can match up to 8 expected surfaces */
1037 struct enumstruct
1039 IDirectDrawSurface *expected[MAXEXPECTED];
1040 UINT count;
1043 static HRESULT WINAPI enumCB(IDirectDrawSurface *surf, DDSURFACEDESC *desc, void *ctx)
1045 int i;
1046 BOOL found = FALSE;
1048 for(i = 0; i < MAXEXPECTED; i++)
1050 if(((struct enumstruct *)ctx)->expected[i] == surf) found = TRUE;
1053 ok(found, "Unexpected surface %p enumerated\n", surf);
1054 ((struct enumstruct *)ctx)->count++;
1055 IDirectDrawSurface_Release(surf);
1056 return DDENUMRET_OK;
1059 static void EnumTest(void)
1061 HRESULT rc;
1062 DDSURFACEDESC ddsd;
1063 IDirectDrawSurface *surface;
1064 struct enumstruct ctx;
1066 ddsd.dwSize = sizeof(ddsd);
1067 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1068 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1069 U2(ddsd).dwMipMapCount = 3;
1070 ddsd.dwWidth = 32;
1071 ddsd.dwHeight = 32;
1072 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
1073 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
1075 memset(&ctx, 0, sizeof(ctx));
1076 ctx.expected[0] = surface;
1077 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[0], &ddsd.ddsCaps, &ctx.expected[1]);
1078 ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1079 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[1], &ddsd.ddsCaps, &ctx.expected[2]);
1080 ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1081 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[2], &ddsd.ddsCaps, &ctx.expected[3]);
1082 ok(rc == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", rc);
1083 ok(!ctx.expected[3], "expected NULL pointer\n");
1084 ctx.count = 0;
1086 rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, &ddsd, &ctx, enumCB);
1087 ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
1088 ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
1090 ctx.count = 0;
1091 rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, NULL, &ctx, enumCB);
1092 ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
1093 ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
1095 IDirectDrawSurface_Release(ctx.expected[2]);
1096 IDirectDrawSurface_Release(ctx.expected[1]);
1097 IDirectDrawSurface_Release(surface);
1100 struct compare
1102 DWORD width, height;
1103 DWORD caps, caps2;
1104 UINT mips;
1107 static HRESULT WINAPI CubeTestPaletteEnum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1109 HRESULT hr;
1111 hr = IDirectDrawSurface7_SetPalette(surface, context);
1112 if (desc->dwWidth == 64) /* This is for first mimpmap */
1113 ok(hr == DDERR_NOTONMIPMAPSUBLEVEL, "SetPalette returned: %x\n",hr);
1114 else
1115 ok(hr == DD_OK, "SetPalette returned: %x\n",hr);
1117 IDirectDrawSurface7_Release(surface);
1119 return DDENUMRET_OK;
1122 static HRESULT WINAPI CubeTestLvl2Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1124 UINT *mips = context;
1126 (*mips)++;
1127 IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1128 context,
1129 CubeTestLvl2Enum);
1131 return DDENUMRET_OK;
1134 static HRESULT WINAPI CubeTestLvl1Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1136 UINT mips = 0;
1137 UINT *num = context;
1138 static const struct compare expected[] =
1141 128, 128,
1142 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1143 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ,
1147 128, 128,
1148 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1149 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ,
1153 128, 128,
1154 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1155 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY,
1159 128, 128,
1160 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1161 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY,
1165 128, 128,
1166 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1167 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX,
1171 64, 64, /* This is the first mipmap */
1172 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1173 DDSCAPS2_MIPMAPSUBLEVEL | DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX,
1178 mips = 0;
1179 IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1180 &mips,
1181 CubeTestLvl2Enum);
1183 ok(desc->dwWidth == expected[*num].width, "Surface width is %d expected %d\n", desc->dwWidth, expected[*num].width);
1184 ok(desc->dwHeight == expected[*num].height, "Surface height is %d expected %d\n", desc->dwHeight, expected[*num].height);
1185 ok(desc->ddsCaps.dwCaps == expected[*num].caps, "Surface caps are %08x expected %08x\n", desc->ddsCaps.dwCaps, expected[*num].caps);
1186 ok(desc->ddsCaps.dwCaps2 == expected[*num].caps2, "Surface caps2 are %08x expected %08x\n", desc->ddsCaps.dwCaps2, expected[*num].caps2);
1187 ok(mips == expected[*num].mips, "Surface has %d mipmaps, expected %d\n", mips, expected[*num].mips);
1189 (*num)++;
1191 IDirectDrawSurface7_Release(surface);
1193 return DDENUMRET_OK;
1196 static void CubeMapTest(void)
1198 IDirectDraw7 *dd7 = NULL;
1199 IDirectDrawSurface7 *cubemap = NULL;
1200 IDirectDrawPalette *palette = NULL;
1201 DDSURFACEDESC2 ddsd;
1202 HRESULT hr;
1203 PALETTEENTRY Table[256];
1204 int i;
1205 UINT num = 0;
1206 UINT ref;
1207 struct enumstruct ctx;
1209 for(i=0; i<256; i++)
1211 Table[i].peRed = 0xff;
1212 Table[i].peGreen = 0;
1213 Table[i].peBlue = 0;
1214 Table[i].peFlags = 0;
1217 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1218 ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1219 if (FAILED(hr)) goto err;
1221 memset(&ddsd, 0, sizeof(ddsd));
1222 ddsd.dwSize = sizeof(ddsd);
1223 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1224 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1225 ddsd.dwWidth = 128;
1226 ddsd.dwHeight = 128;
1227 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1228 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1230 /* D3DFMT_R5G6B5 */
1231 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1232 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1233 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1234 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1235 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1237 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1238 if (FAILED(hr))
1240 skip("Can't create cubemap surface\n");
1241 goto err;
1244 hr = IDirectDrawSurface7_GetSurfaceDesc(cubemap, &ddsd);
1245 ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
1246 ok(ddsd.ddsCaps.dwCaps == (DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX),
1247 "Root Caps are %08x\n", ddsd.ddsCaps.dwCaps);
1248 ok(ddsd.ddsCaps.dwCaps2 == (DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP),
1249 "Root Caps2 are %08x\n", ddsd.ddsCaps.dwCaps2);
1251 IDirectDrawSurface7_EnumAttachedSurfaces(cubemap,
1252 &num,
1253 CubeTestLvl1Enum);
1254 ok(num == 6, "Surface has %d attachments\n", num);
1255 IDirectDrawSurface7_Release(cubemap);
1257 /* What happens if I do not specify any faces? */
1258 memset(&ddsd, 0, sizeof(ddsd));
1259 ddsd.dwSize = sizeof(ddsd);
1260 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1261 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1262 ddsd.dwWidth = 128;
1263 ddsd.dwHeight = 128;
1264 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1265 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP;
1267 /* D3DFMT_R5G6B5 */
1268 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1269 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1270 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1271 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1272 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1274 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1275 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7::CreateSurface asking for a cube map without faces returned %08x\n", hr);
1277 /* Cube map faces without a cube map? */
1278 memset(&ddsd, 0, sizeof(ddsd));
1279 ddsd.dwSize = sizeof(ddsd);
1280 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1281 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1282 ddsd.dwWidth = 128;
1283 ddsd.dwHeight = 128;
1284 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1285 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_ALLFACES;
1287 /* D3DFMT_R5G6B5 */
1288 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1289 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1290 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1291 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1292 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1294 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1295 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1297 memset(&ddsd, 0, sizeof(ddsd));
1298 ddsd.dwSize = sizeof(ddsd);
1299 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1300 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1301 ddsd.dwWidth = 128;
1302 ddsd.dwHeight = 128;
1303 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1304 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEX;
1306 /* D3DFMT_R5G6B5 */
1307 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1308 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1309 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1310 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1311 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1313 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1314 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1316 memset(&ddsd, 0, sizeof(ddsd));
1317 ddsd.dwSize = sizeof(ddsd);
1318 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1319 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1320 ddsd.dwWidth = 128;
1321 ddsd.dwHeight = 128;
1322 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1323 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1325 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1326 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
1328 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1329 if (FAILED(hr))
1331 skip("Can't create palletized cubemap surface\n");
1332 goto err;
1335 hr = IDirectDraw7_CreatePalette(dd7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
1336 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
1338 hr = IDirectDrawSurface7_EnumAttachedSurfaces(cubemap, palette, CubeTestPaletteEnum);
1339 ok(hr == DD_OK, "EnumAttachedSurfaces failed\n");
1341 ref = getRefcount((IUnknown *) palette);
1342 ok(ref == 6, "Refcount is %u, expected 1\n", ref);
1344 IDirectDrawSurface7_Release(cubemap);
1346 ref = getRefcount((IUnknown *) palette);
1347 ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1349 IDirectDrawPalette_Release(palette);
1351 /* Make sure everything is cleaned up properly. Use the enumSurfaces test infrastructure */
1352 memset(&ctx, 0, sizeof(ctx));
1353 memset(&ddsd, 0, sizeof(ddsd));
1354 ddsd.dwSize = sizeof(DDSURFACEDESC);
1355 hr = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, (DDSURFACEDESC *) &ddsd, (void *) &ctx, enumCB);
1356 ok(hr == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", hr);
1357 ok(ctx.count == 0, "%d surfaces enumerated, expected 0\n", ctx.count);
1359 err:
1360 if (dd7) IDirectDraw7_Release(dd7);
1363 static void test_lockrect_invalid(void)
1365 unsigned int i, j;
1367 RECT valid[] = {
1368 {60, 60, 68, 68},
1369 {60, 60, 60, 68},
1370 {60, 60, 68, 60},
1371 {120, 60, 128, 68},
1372 {60, 120, 68, 128},
1375 RECT invalid[] = {
1376 {68, 60, 60, 68}, /* left > right */
1377 {60, 68, 68, 60}, /* top > bottom */
1378 {-8, 60, 0, 68}, /* left < surface */
1379 {60, -8, 68, 0}, /* top < surface */
1380 {-16, 60, -8, 68}, /* right < surface */
1381 {60, -16, 68, -8}, /* bottom < surface */
1382 {60, 60, 136, 68}, /* right > surface */
1383 {60, 60, 68, 136}, /* bottom > surface */
1384 {136, 60, 144, 68}, /* left > surface */
1385 {60, 136, 68, 144}, /* top > surface */
1388 const DWORD dds_caps[] = {
1389 DDSCAPS_OFFSCREENPLAIN
1392 for (j = 0; j < (sizeof(dds_caps) / sizeof(*dds_caps)); ++j)
1394 IDirectDrawSurface *surface = 0;
1395 DDSURFACEDESC surface_desc = {0};
1396 DDSURFACEDESC locked_desc = {0};
1397 HRESULT hr;
1399 surface_desc.dwSize = sizeof(surface_desc);
1400 surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
1401 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1402 surface_desc.ddsCaps.dwCaps = dds_caps[j];
1403 surface_desc.dwWidth = 128;
1404 surface_desc.dwHeight = 128;
1405 surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
1406 U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
1407 U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xFF0000;
1408 U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00FF00;
1409 U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000FF;
1411 hr = IDirectDraw_CreateSurface(lpDD, &surface_desc, &surface, NULL);
1412 ok(SUCCEEDED(hr), "CreateSurface failed (0x%08x)\n", hr);
1413 if (FAILED(hr))
1415 skip("failed to create surface\n");
1416 continue;
1419 hr = IDirectDrawSurface_Lock(surface, NULL, NULL, DDLOCK_WAIT, NULL);
1420 ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for NULL DDSURFACEDESC,"
1421 " expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, DDERR_INVALIDPARAMS);
1423 for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i)
1425 RECT *rect = &valid[i];
1427 memset(&locked_desc, 0, sizeof(locked_desc));
1428 locked_desc.dwSize = sizeof(locked_desc);
1430 hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1431 ok(SUCCEEDED(hr), "Lock failed (0x%08x) for rect [%d, %d]->[%d, %d]\n",
1432 hr, rect->left, rect->top, rect->right, rect->bottom);
1434 hr = IDirectDrawSurface_Unlock(surface, NULL);
1435 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1438 for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i)
1440 RECT *rect = &invalid[i];
1442 memset(&locked_desc, 1, sizeof(locked_desc));
1443 locked_desc.dwSize = sizeof(locked_desc);
1445 hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1446 ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for rect [%d, %d]->[%d, %d]"
1447 ", expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, rect->left, rect->top,
1448 rect->right, rect->bottom, DDERR_INVALIDPARAMS);
1449 ok(!locked_desc.lpSurface, "IDirectDrawSurface_Lock did not set lpSurface in the surface desc to zero.\n");
1452 hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1453 ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = NULL) failed (0x%08x)\n", hr);
1454 hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1455 ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned 0x%08x\n", hr);
1456 if(SUCCEEDED(hr)) {
1457 hr = IDirectDrawSurface_Unlock(surface, NULL);
1458 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1460 hr = IDirectDrawSurface_Unlock(surface, NULL);
1461 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1463 memset(&locked_desc, 0, sizeof(locked_desc));
1464 locked_desc.dwSize = sizeof(locked_desc);
1465 hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1466 ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1467 valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1468 hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1469 ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1470 valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1472 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
1473 * Afterwards unlocking the surface fails(NULL rectangle, and both locked rectangles
1476 hr = IDirectDrawSurface_Unlock(surface, NULL);
1477 ok(hr == DD_OK, "Unlock returned (0x%08x)\n", hr);
1479 IDirectDrawSurface_Release(surface);
1483 static void CompressedTest(void)
1485 HRESULT hr;
1486 IDirectDrawSurface7 *surface;
1487 DDSURFACEDESC2 ddsd, ddsd2;
1488 IDirectDraw7 *dd7 = NULL;
1489 RECT r = { 0, 0, 128, 128 };
1490 RECT r2 = { 32, 32, 64, 64 };
1492 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1493 ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1495 memset(&ddsd, 0, sizeof(ddsd));
1496 ddsd.dwSize = sizeof(ddsd);
1497 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1498 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1499 ddsd.dwWidth = 128;
1500 ddsd.dwHeight = 128;
1501 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
1502 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
1503 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1505 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1506 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1507 if (FAILED(hr))
1509 skip("failed to create surface\n");
1510 return;
1513 memset(&ddsd2, 0, sizeof(ddsd2));
1514 ddsd2.dwSize = sizeof(ddsd2);
1515 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1516 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1517 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1519 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1520 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1521 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1522 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1523 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1524 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1525 ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1526 ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1527 IDirectDrawSurface7_Release(surface);
1529 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1530 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1531 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1532 if (FAILED(hr))
1534 skip("failed to create surface\n");
1535 return;
1538 memset(&ddsd2, 0, sizeof(ddsd2));
1539 ddsd2.dwSize = sizeof(ddsd2);
1540 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1541 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1542 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1544 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1545 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1546 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1547 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1548 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1549 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1550 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1551 IDirectDrawSurface7_Release(surface);
1553 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1554 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1555 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1556 if (FAILED(hr))
1558 skip("failed to create surface\n");
1559 return;
1562 memset(&ddsd2, 0, sizeof(ddsd2));
1563 ddsd2.dwSize = sizeof(ddsd2);
1564 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1565 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1566 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1568 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1569 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1570 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1571 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1572 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1573 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1574 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1575 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
1577 memset(&ddsd2, 0, sizeof(ddsd2));
1578 ddsd2.dwSize = sizeof(ddsd2);
1579 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1581 /* Show that the description is not changed when locking the surface. What is really interesting
1582 * about this is that DDSD_LPSURFACE isn't set.
1584 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
1585 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1587 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1588 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1589 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1590 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1591 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1592 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1593 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1594 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1596 hr = IDirectDrawSurface7_Unlock(surface, NULL);
1597 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1599 /* Now what about a locking rect? */
1600 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
1601 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1603 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1604 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1605 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1606 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1607 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1608 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1609 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1610 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1612 hr = IDirectDrawSurface7_Unlock(surface, &r);
1613 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1615 /* Now what about a different locking offset? */
1616 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
1617 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1619 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1620 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1621 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1622 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1623 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1624 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1625 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1626 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1628 hr = IDirectDrawSurface7_Unlock(surface, &r2);
1629 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1630 IDirectDrawSurface7_Release(surface);
1632 /* Try this with video memory. A kind of surprise. It still has the LINEARSIZE flag set,
1633 * but seems to have a pitch instead.
1635 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
1636 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1638 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1639 ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW || hr == DDERR_INVALIDPARAMS ||
1640 broken(hr == DDERR_NODIRECTDRAWHW), "CreateSurface returned %08x\n", hr);
1642 /* Not supported everywhere */
1643 if(SUCCEEDED(hr))
1645 memset(&ddsd2, 0, sizeof(ddsd2));
1646 ddsd2.dwSize = sizeof(ddsd2);
1647 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1648 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1649 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1651 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1652 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1653 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1654 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1655 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1656 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1657 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1658 ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1659 IDirectDrawSurface7_Release(surface);
1661 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1662 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1663 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1665 memset(&ddsd2, 0, sizeof(ddsd2));
1666 ddsd2.dwSize = sizeof(ddsd2);
1667 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1668 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1669 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1671 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1672 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1673 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1674 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1675 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1676 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1677 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1678 IDirectDrawSurface7_Release(surface);
1680 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1681 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1682 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1684 memset(&ddsd2, 0, sizeof(ddsd2));
1685 ddsd2.dwSize = sizeof(ddsd2);
1686 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1687 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1688 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1690 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1691 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1692 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1693 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1694 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1695 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1696 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1697 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
1699 memset(&ddsd2, 0, sizeof(ddsd2));
1700 ddsd2.dwSize = sizeof(ddsd2);
1701 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1703 /* Show that the description is not changed when locking the surface. What is really interesting
1704 * about this is that DDSD_LPSURFACE isn't set.
1706 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
1707 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1709 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1710 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1711 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1712 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1713 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1714 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1715 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1716 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1718 hr = IDirectDrawSurface7_Unlock(surface, NULL);
1719 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1721 /* Now what about a locking rect? */
1722 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
1723 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1725 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1726 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1727 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1728 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1729 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1730 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1731 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1732 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1734 hr = IDirectDrawSurface7_Unlock(surface, &r);
1735 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1737 /* Now what about a different locking offset? */
1738 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
1739 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1741 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1742 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1743 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1744 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1745 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1746 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1747 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1748 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1750 hr = IDirectDrawSurface7_Unlock(surface, &r2);
1751 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1753 IDirectDrawSurface7_Release(surface);
1755 else
1757 skip("Hardware DXTN textures not supported\n");
1760 /* What happens to managed textures? Interestingly, Windows reports them as being in system
1761 * memory. The linear size fits again.
1763 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1764 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
1765 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1767 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1768 ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW, "CreateSurface returned %08x\n", hr);
1770 /* Not supported everywhere */
1771 if(SUCCEEDED(hr))
1773 memset(&ddsd2, 0, sizeof(ddsd2));
1774 ddsd2.dwSize = sizeof(ddsd2);
1775 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1776 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1777 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1779 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1780 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1781 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1782 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1783 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1784 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1785 ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1786 ok(ddsd2.ddsCaps.dwCaps2 == DDSCAPS2_TEXTUREMANAGE, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1787 IDirectDrawSurface7_Release(surface);
1789 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1790 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1791 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1793 memset(&ddsd2, 0, sizeof(ddsd2));
1794 ddsd2.dwSize = sizeof(ddsd2);
1795 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1796 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1797 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1799 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1800 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1801 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1802 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1803 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1804 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1805 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1806 IDirectDrawSurface7_Release(surface);
1808 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1809 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1810 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1812 memset(&ddsd2, 0, sizeof(ddsd2));
1813 ddsd2.dwSize = sizeof(ddsd2);
1814 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1815 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1816 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1818 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1819 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1820 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1821 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1822 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1823 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1824 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1825 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
1827 memset(&ddsd2, 0, sizeof(ddsd2));
1828 ddsd2.dwSize = sizeof(ddsd2);
1829 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1831 /* Show that the description is not changed when locking the surface. What is really interesting
1832 * about this is that DDSD_LPSURFACE isn't set.
1834 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
1835 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1837 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1838 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1839 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1840 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1841 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1842 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1843 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1844 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1846 hr = IDirectDrawSurface7_Unlock(surface, NULL);
1847 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1849 /* Now what about a locking rect? */
1850 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
1851 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1853 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1854 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1855 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1856 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1857 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1858 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1859 ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
1860 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1862 hr = IDirectDrawSurface7_Unlock(surface, &r);
1863 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1865 /* Now what about a different locking offset? */
1866 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
1867 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1869 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1870 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1871 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1872 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1873 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1874 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1875 ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
1876 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1878 hr = IDirectDrawSurface7_Unlock(surface, &r2);
1879 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1881 IDirectDrawSurface7_Release(surface);
1883 else
1885 skip("Hardware DXTN textures not supported\n");
1888 IDirectDraw7_Release(dd7);
1891 static void SizeTest(void)
1893 IDirectDrawSurface *dsurface = NULL;
1894 DDSURFACEDESC desc;
1895 HRESULT ret;
1896 HWND window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1897 100, 100, 160, 160, NULL, NULL, NULL, NULL);
1899 /* Create an offscreen surface surface without a size */
1900 ZeroMemory(&desc, sizeof(desc));
1901 desc.dwSize = sizeof(desc);
1902 desc.dwFlags = DDSD_CAPS;
1903 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
1904 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1905 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without a size info returned %08x (dsurface=%p)\n", ret, dsurface);
1906 if(dsurface)
1908 trace("Surface at %p\n", dsurface);
1909 IDirectDrawSurface_Release(dsurface);
1910 dsurface = NULL;
1913 /* Create an offscreen surface surface with only a width parameter */
1914 ZeroMemory(&desc, sizeof(desc));
1915 desc.dwSize = sizeof(desc);
1916 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH;
1917 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
1918 desc.dwWidth = 128;
1919 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1920 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without height info returned %08x\n", ret);
1921 if(dsurface)
1923 IDirectDrawSurface_Release(dsurface);
1924 dsurface = NULL;
1927 /* Create an offscreen surface surface with only a height parameter */
1928 ZeroMemory(&desc, sizeof(desc));
1929 desc.dwSize = sizeof(desc);
1930 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT;
1931 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
1932 desc.dwHeight = 128;
1933 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1934 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without width info returned %08x\n", ret);
1935 if(dsurface)
1937 IDirectDrawSurface_Release(dsurface);
1938 dsurface = NULL;
1941 /* Test 0 height. */
1942 memset(&desc, 0, sizeof(desc));
1943 desc.dwSize = sizeof(desc);
1944 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1945 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1946 desc.dwWidth = 1;
1947 desc.dwHeight = 0;
1948 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1949 ok(ret == DDERR_INVALIDPARAMS, "Creating a 0 height surface returned %#x, expected DDERR_INVALIDPARAMS.\n", ret);
1950 if (SUCCEEDED(ret)) IDirectDrawSurface_Release(dsurface);
1951 dsurface = NULL;
1953 /* Test 0 width. */
1954 memset(&desc, 0, sizeof(desc));
1955 desc.dwSize = sizeof(desc);
1956 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1957 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1958 desc.dwWidth = 0;
1959 desc.dwHeight = 1;
1960 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1961 ok(ret == DDERR_INVALIDPARAMS, "Creating a 0 width surface returned %#x, expected DDERR_INVALIDPARAMS.\n", ret);
1962 if (SUCCEEDED(ret)) IDirectDrawSurface_Release(dsurface);
1963 dsurface = NULL;
1965 /* Sanity check */
1966 ZeroMemory(&desc, sizeof(desc));
1967 desc.dwSize = sizeof(desc);
1968 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
1969 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
1970 desc.dwHeight = 128;
1971 desc.dwWidth = 128;
1972 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1973 ok(ret == DD_OK, "Creating an offscreen plain surface with width and height info returned %08x\n", ret);
1974 if(dsurface)
1976 IDirectDrawSurface_Release(dsurface);
1977 dsurface = NULL;
1980 /* Test a primary surface size */
1981 ret = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_NORMAL);
1982 ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
1984 ZeroMemory(&desc, sizeof(desc));
1985 desc.dwSize = sizeof(desc);
1986 desc.dwFlags = DDSD_CAPS;
1987 desc.ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
1988 desc.dwHeight = 128; /* Keep them set to check what happens */
1989 desc.dwWidth = 128; /* Keep them set to check what happens */
1990 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1991 ok(ret == DD_OK, "Creating a primary surface without width and height info returned %08x\n", ret);
1992 if(dsurface)
1994 ret = IDirectDrawSurface_GetSurfaceDesc(dsurface, &desc);
1995 ok(ret == DD_OK, "GetSurfaceDesc returned %x\n", ret);
1997 IDirectDrawSurface_Release(dsurface);
1998 dsurface = NULL;
2000 ok(desc.dwFlags & DDSD_WIDTH, "Primary surface doesn't have width set\n");
2001 ok(desc.dwFlags & DDSD_HEIGHT, "Primary surface doesn't have height set\n");
2002 ok(desc.dwWidth == GetSystemMetrics(SM_CXSCREEN), "Surface width differs from screen width\n");
2003 ok(desc.dwHeight == GetSystemMetrics(SM_CYSCREEN), "Surface height differs from screen height\n");
2005 ret = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
2006 ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2009 static void BltParamTest(void)
2011 IDirectDrawSurface *surface1 = NULL, *surface2 = NULL;
2012 DDSURFACEDESC desc;
2013 HRESULT hr;
2014 DDBLTFX BltFx;
2015 RECT valid = {10, 10, 20, 20};
2016 RECT invalid1 = {20, 10, 10, 20};
2017 RECT invalid2 = {20, 20, 20, 20};
2018 RECT invalid3 = {-1, -1, 20, 20};
2019 RECT invalid4 = {60, 60, 70, 70};
2021 memset(&desc, 0, sizeof(desc));
2022 desc.dwSize = sizeof(desc);
2023 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2024 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2025 desc.dwHeight = 128;
2026 desc.dwWidth = 128;
2027 hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface1, NULL);
2028 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2030 desc.dwHeight = 64;
2031 desc.dwWidth = 64;
2032 hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface2, NULL);
2033 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2035 if(0)
2037 /* This crashes */
2038 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, NULL, NULL, 0);
2039 ok(hr == DD_OK, "BltFast from NULL surface returned %08x\n", hr);
2041 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, NULL, 0);
2042 ok(hr == DD_OK, "BltFast from smaller to bigger surface returned %08x\n", hr);
2043 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, NULL, 0);
2044 ok(hr == DDERR_INVALIDRECT, "BltFast from bigger to smaller surface returned %08x\n", hr);
2045 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &valid, 0);
2046 ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle returned %08x\n", hr);
2047 hr = IDirectDrawSurface_BltFast(surface2, 60, 60, surface1, &valid, 0);
2048 ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2049 hr = IDirectDrawSurface_BltFast(surface1, 90, 90, surface2, NULL, 0);
2050 ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2052 hr = IDirectDrawSurface_BltFast(surface1, -10, 0, surface2, NULL, 0);
2053 ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
2054 hr = IDirectDrawSurface_BltFast(surface1, 0, -10, surface2, NULL, 0);
2055 ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
2056 hr = IDirectDrawSurface_BltFast(surface2, 20, 20, surface1, &valid, 0);
2057 ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle and offset returned %08x\n", hr);
2059 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid1, 0);
2060 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 1 returned %08x\n", hr);
2061 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid2, 0);
2062 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 2 returned %08x\n", hr);
2063 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid3, 0);
2064 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2065 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, &invalid4, 0);
2066 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2067 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface1, NULL, 0);
2068 ok(hr == DD_OK, "BltFast blitting a surface onto itself returned %08x\n", hr);
2070 /* Blt(non-fast) tests */
2071 memset(&BltFx, 0, sizeof(BltFx));
2072 BltFx.dwSize = sizeof(BltFx);
2073 U5(BltFx).dwFillColor = 0xaabbccdd;
2075 hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2076 ok(hr == DD_OK, "IDirectDrawSurface_Blt with a valid rectangle for color fill returned %08x\n", hr);
2077 hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, &invalid3, DDBLT_COLORFILL, &BltFx);
2078 ok(hr == DD_OK, "IDirectDrawSurface_Blt with an invalid, unused rectangle returned %08x\n", hr);
2079 hr = IDirectDrawSurface_Blt(surface2, &invalid1, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2080 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2081 hr = IDirectDrawSurface_Blt(surface2, &invalid2, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2082 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2083 hr = IDirectDrawSurface_Blt(surface2, &invalid3, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2084 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2085 hr = IDirectDrawSurface_Blt(surface2, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2086 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2088 /* Valid on surface 1 */
2089 hr = IDirectDrawSurface_Blt(surface1, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2090 ok(hr == DD_OK, "IDirectDrawSurface_Blt with a subrectangle fill returned %08x\n", hr);
2092 /* Works - stretched blit */
2093 hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, NULL, 0, NULL);
2094 ok(hr == DD_OK, "IDirectDrawSurface_Blt from a smaller to a bigger surface returned %08x\n", hr);
2095 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, NULL, 0, NULL);
2096 ok(hr == DD_OK, "IDirectDrawSurface_Blt from a bigger to a smaller surface %08x\n", hr);
2098 /* Invalid dest rects in sourced blits */
2099 hr = IDirectDrawSurface_Blt(surface2, &invalid1, surface1, NULL, 0, NULL);
2100 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2101 hr = IDirectDrawSurface_Blt(surface2, &invalid2, surface1, NULL, 0, NULL);
2102 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2103 hr = IDirectDrawSurface_Blt(surface2, &invalid3, surface1, NULL, 0, NULL);
2104 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2105 hr = IDirectDrawSurface_Blt(surface2, &invalid4, surface1, NULL, 0, NULL);
2106 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2108 /* Invalid src rects */
2109 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid1, 0, NULL);
2110 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2111 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid2, 0, NULL);
2112 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2113 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid3, 0, NULL);
2114 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2115 hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, &invalid4, 0, NULL);
2116 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2118 IDirectDrawSurface_Release(surface1);
2119 IDirectDrawSurface_Release(surface2);
2122 static void PaletteTest(void)
2124 HRESULT hr;
2125 IDirectDrawSurface *lpSurf = NULL;
2126 IDirectDrawSurface *backbuffer = NULL;
2127 DDSCAPS ddscaps;
2128 DDSURFACEDESC ddsd;
2129 IDirectDrawPalette *palette = NULL;
2130 PALETTEENTRY Table[256];
2131 PALETTEENTRY palEntries[256];
2132 int i;
2134 for(i=0; i<256; i++)
2136 Table[i].peRed = 0xff;
2137 Table[i].peGreen = 0;
2138 Table[i].peBlue = 0;
2139 Table[i].peFlags = 0;
2142 /* Create a 8bit palette without DDPCAPS_ALLOW256 set */
2143 hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_8BIT, Table, &palette, NULL);
2144 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2145 if (FAILED(hr)) goto err;
2146 /* Read back the palette and verify the entries. Without DDPCAPS_ALLOW256 set
2147 / entry 0 and 255 should have been overwritten with black and white */
2148 hr = IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2149 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2150 if(hr == DD_OK)
2152 ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2153 "Palette entry 0 of a palette without DDPCAPS_ALLOW256 set should be (0,0,0) but it is (%d,%d,%d)\n",
2154 palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2155 ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2156 "Palette entry 255 of a palette without DDPCAPS_ALLOW256 set should be (255,255,255) but it is (%d,%d,%d)\n",
2157 palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2159 /* Entry 1-254 should contain red */
2160 for(i=1; i<255; i++)
2161 ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2162 "Palette entry %d should have contained (255,0,0) but was set to (%d,%d,%d)\n",
2163 i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2166 /* CreatePalette without DDPCAPS_ALLOW256 ignores entry 0 and 255,
2167 / now check we are able to update the entries afterwards. */
2168 hr = IDirectDrawPalette_SetEntries(palette , 0, 0, 256, &Table[0]);
2169 ok(hr == DD_OK, "SetEntries failed with %08x\n", hr);
2170 hr = IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2171 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2172 if(hr == DD_OK)
2174 ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2175 "Palette entry 0 should have been set to (0,0,0) but it contains (%d,%d,%d)\n",
2176 palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2177 ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2178 "Palette entry 255 should have been set to (255,255,255) but it contains (%d,%d,%d)\n",
2179 palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2181 IDirectDrawPalette_Release(palette);
2183 /* Create a 8bit palette with DDPCAPS_ALLOW256 set */
2184 hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
2185 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2186 if (FAILED(hr)) goto err;
2188 hr = IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2189 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2190 if(hr == DD_OK)
2192 /* All entries should contain red */
2193 for(i=0; i<256; i++)
2194 ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2195 "Palette entry %d should have contained (255,0,0) but was set to (%d,%d,%d)\n",
2196 i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2199 /* Try to set palette to a non-palettized surface */
2200 ddsd.dwSize = sizeof(ddsd);
2201 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2202 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2203 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2204 ddsd.dwWidth = 800;
2205 ddsd.dwHeight = 600;
2206 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2207 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
2208 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
2209 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
2210 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
2211 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurf, NULL);
2212 ok(hr==DD_OK, "CreateSurface returned: %x\n",hr);
2213 if (FAILED(hr))
2215 skip("failed to create surface\n");
2216 goto err;
2219 hr = IDirectDrawSurface_SetPalette(lpSurf, palette);
2220 ok(hr == DDERR_INVALIDPIXELFORMAT, "CreateSurface returned: %x\n",hr);
2222 IDirectDrawPalette_Release(palette);
2223 palette = NULL;
2225 hr = IDirectDrawSurface_GetPalette(lpSurf, &palette);
2226 ok(hr == DDERR_NOPALETTEATTACHED, "CreateSurface returned: %x\n",hr);
2228 err:
2230 if (lpSurf) IDirectDrawSurface_Release(lpSurf);
2231 if (palette) IDirectDrawPalette_Release(palette);
2233 hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
2234 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2236 ddsd.dwSize = sizeof(ddsd);
2237 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2238 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_BACKBUFFERCOUNT;
2239 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
2240 ddsd.dwWidth = 64;
2241 ddsd.dwHeight = 64;
2242 ddsd.dwBackBufferCount = 1;
2243 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2244 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
2246 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurf, NULL);
2247 ok(hr==DD_OK, "CreateSurface returned: %x\n",hr);
2248 if (FAILED(hr))
2250 skip("failed to create surface\n");
2251 return;
2254 ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
2255 hr = IDirectDrawSurface_GetAttachedSurface(lpSurf, &ddscaps, &backbuffer);
2256 ok(hr == DD_OK, "GetAttachedSurface returned: %x\n",hr);
2258 hr = IDirectDrawSurface_SetPalette(backbuffer, palette);
2259 ok(hr == DD_OK, "SetPalette returned: %x\n",hr);
2261 IDirectDrawPalette_Release(palette);
2262 palette = NULL;
2264 hr = IDirectDrawSurface_GetPalette(backbuffer, &palette);
2265 ok(hr == DD_OK, "CreateSurface returned: %x\n",hr);
2267 IDirectDrawSurface_Release(backbuffer);
2268 IDirectDrawSurface_Release(lpSurf);
2271 static void StructSizeTest(void)
2273 IDirectDrawSurface *surface1;
2274 IDirectDrawSurface7 *surface7;
2275 union {
2276 DDSURFACEDESC desc1;
2277 DDSURFACEDESC2 desc2;
2278 char blob[1024]; /* To get a bunch of writable memory */
2279 } desc;
2280 DDSURFACEDESC create;
2281 HRESULT hr;
2283 memset(&desc, 0, sizeof(desc));
2284 memset(&create, 0, sizeof(create));
2286 memset(&create, 0, sizeof(create));
2287 create.dwSize = sizeof(create);
2288 create.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2289 create.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2290 create.dwHeight = 128;
2291 create.dwWidth = 128;
2292 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2293 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2294 hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface7, (void **) &surface7);
2295 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2297 desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2298 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2299 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2300 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2301 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2303 desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2304 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2305 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2306 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2307 ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2309 desc.desc2.dwSize = 0;
2310 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2311 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2312 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2313 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2315 desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2316 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2317 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2318 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2319 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2321 desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2322 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2323 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2324 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2325 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2327 /* Tests for Lock() */
2329 desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2330 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2331 ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2332 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2333 ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2334 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2335 ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2336 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2337 ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2339 desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2340 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2341 ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2342 ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2343 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2344 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2345 ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2346 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2347 ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2349 desc.desc2.dwSize = 0;
2350 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2351 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size 0 returned %08x\n", hr);
2352 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2353 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2354 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size 0 returned %08x\n", hr);
2355 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2357 desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2358 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2359 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2360 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2361 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2362 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2363 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2365 desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2366 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2367 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2368 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2369 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2370 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2371 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2373 IDirectDrawSurface7_Release(surface7);
2374 IDirectDrawSurface_Release(surface1);
2377 static void SurfaceCapsTest(void)
2379 DDSURFACEDESC create;
2380 DDSURFACEDESC desc;
2381 HRESULT hr;
2382 IDirectDrawSurface *surface1 = NULL;
2383 DDSURFACEDESC2 create2, desc2;
2384 IDirectDrawSurface7 *surface7 = NULL;
2385 IDirectDraw7 *dd7 = NULL;
2386 DWORD create_caps[] = {
2387 DDSCAPS_OFFSCREENPLAIN,
2388 DDSCAPS_TEXTURE,
2389 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD,
2391 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2392 DDSCAPS_PRIMARYSURFACE,
2393 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY,
2394 DDSCAPS_3DDEVICE,
2395 DDSCAPS_ZBUFFER,
2396 DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN
2398 DWORD expected_caps[] = {
2399 DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2400 DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2401 DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD,
2402 DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2403 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2404 DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_VISIBLE,
2405 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_VISIBLE,
2406 DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2407 DDSCAPS_ZBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY,
2408 DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM
2410 UINT i;
2412 /* Tests various surface flags, what changes do they undergo during
2413 * surface creation. Forsaken engine expects texture surfaces without
2414 * memory flag to get a video memory flag right after creation. */
2416 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
2418 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
2419 return ;
2422 for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2424 memset(&create, 0, sizeof(create));
2425 create.dwSize = sizeof(create);
2426 create.ddsCaps.dwCaps = create_caps[i];
2427 create.dwFlags = DDSD_CAPS;
2429 if (!(create.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2431 create.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2432 create.dwHeight = 128;
2433 create.dwWidth = 128;
2436 if (create.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
2438 create.dwFlags |= DDSD_PIXELFORMAT;
2439 create.ddpfPixelFormat.dwSize = sizeof(create.ddpfPixelFormat);
2440 create.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2441 U1(create.ddpfPixelFormat).dwZBufferBitDepth = 16;
2442 U3(create.ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
2445 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2446 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2448 if (SUCCEEDED(hr))
2450 memset(&desc, 0, sizeof(desc));
2451 desc.dwSize = sizeof(DDSURFACEDESC);
2452 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc);
2453 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2455 ok(desc.ddsCaps.dwCaps == expected_caps[i],
2456 "GetSurfaceDesc test %d returned caps %x, expected %x\n",
2457 i, desc.ddsCaps.dwCaps, expected_caps[i]);
2459 IDirectDrawSurface_Release(surface1);
2463 /* Test for differences in ddraw 7 */
2464 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2465 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
2466 if (FAILED(hr))
2468 skip("Failed to get IDirectDraw7 interface, skipping tests\n");
2470 else
2472 for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2474 memset(&create2, 0, sizeof(create2));
2475 create2.dwSize = sizeof(create2);
2476 create2.ddsCaps.dwCaps = create_caps[i];
2477 create2.dwFlags = DDSD_CAPS;
2479 if (!(create2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2481 create2.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2482 create2.dwHeight = 128;
2483 create2.dwWidth = 128;
2486 if (create2.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
2488 create2.dwFlags |= DDSD_PIXELFORMAT;
2489 U4(create2).ddpfPixelFormat.dwSize = sizeof(U4(create2).ddpfPixelFormat);
2490 U4(create2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2491 U1(U4(create2).ddpfPixelFormat).dwZBufferBitDepth = 16;
2492 U3(U4(create2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
2495 hr = IDirectDraw7_CreateSurface(dd7, &create2, &surface7, NULL);
2496 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2498 if (SUCCEEDED(hr))
2500 memset(&desc2, 0, sizeof(desc2));
2501 desc2.dwSize = sizeof(DDSURFACEDESC2);
2502 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc2);
2503 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2505 ok(desc2.ddsCaps.dwCaps == expected_caps[i],
2506 "GetSurfaceDesc test %d returned caps %x, expected %x\n",
2507 i, desc2.ddsCaps.dwCaps, expected_caps[i]);
2509 IDirectDrawSurface7_Release(surface7);
2513 IDirectDraw7_Release(dd7);
2516 memset(&create, 0, sizeof(create));
2517 create.dwSize = sizeof(create);
2518 create.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2519 create.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY;
2520 create.dwWidth = 64;
2521 create.dwHeight = 64;
2522 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2523 ok(hr == DDERR_INVALIDCAPS, "Creating a SYSMEM | VIDMEM surface returned 0x%08x, expected DDERR_INVALIDCAPS\n", hr);
2524 if(surface1) IDirectDrawSurface_Release(surface1);
2527 static BOOL can_create_primary_surface(void)
2529 DDSURFACEDESC ddsd;
2530 IDirectDrawSurface *surface;
2531 HRESULT hr;
2533 memset(&ddsd, 0, sizeof(ddsd));
2534 ddsd.dwSize = sizeof(ddsd);
2535 ddsd.dwFlags = DDSD_CAPS;
2536 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2537 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2538 if(FAILED(hr)) return FALSE;
2539 IDirectDrawSurface_Release(surface);
2540 return TRUE;
2543 static void dctest_surf(IDirectDrawSurface *surf, int ddsdver) {
2544 HRESULT hr;
2545 HDC dc, dc2 = (HDC) 0x1234;
2546 DDSURFACEDESC ddsd;
2547 DDSURFACEDESC2 ddsd2;
2549 memset(&ddsd, 0, sizeof(ddsd));
2550 ddsd.dwSize = sizeof(ddsd);
2551 memset(&ddsd2, 0, sizeof(ddsd2));
2552 ddsd2.dwSize = sizeof(ddsd2);
2554 hr = IDirectDrawSurface_GetDC(surf, &dc);
2555 ok(hr == DD_OK, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
2557 hr = IDirectDrawSurface_GetDC(surf, &dc2);
2558 ok(hr == DDERR_DCALREADYCREATED, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
2559 ok(dc2 == (HDC) 0x1234, "The failed GetDC call changed the dc: %p\n", dc2);
2561 hr = IDirectDrawSurface_Lock(surf, NULL, ddsdver == 1 ? &ddsd : ((DDSURFACEDESC *) &ddsd2), 0, NULL);
2562 ok(hr == DDERR_SURFACEBUSY, "IDirectDrawSurface_Lock returned 0x%08x, expected DDERR_ALREADYLOCKED\n", hr);
2564 hr = IDirectDrawSurface_ReleaseDC(surf, dc);
2565 ok(hr == DD_OK, "IDirectDrawSurface_ReleaseDC failed: 0x%08x\n", hr);
2566 hr = IDirectDrawSurface_ReleaseDC(surf, dc);
2567 ok(hr == DDERR_NODC, "IDirectDrawSurface_ReleaseDC returned 0x%08x, expected DDERR_NODC\n", hr);
2570 static void GetDCTest(void)
2572 DDSURFACEDESC ddsd;
2573 DDSURFACEDESC2 ddsd2;
2574 IDirectDrawSurface *surf;
2575 IDirectDrawSurface2 *surf2;
2576 IDirectDrawSurface4 *surf4;
2577 IDirectDrawSurface7 *surf7;
2578 IDirectDrawSurface *tmp;
2579 IDirectDrawSurface7 *tmp7;
2580 HRESULT hr;
2581 IDirectDraw2 *dd2;
2582 IDirectDraw4 *dd4;
2583 IDirectDraw7 *dd7;
2584 HDC dc;
2585 ULONG ref;
2587 memset(&ddsd, 0, sizeof(ddsd));
2588 ddsd.dwSize = sizeof(ddsd);
2589 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2590 ddsd.dwWidth = 64;
2591 ddsd.dwHeight = 64;
2592 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2593 memset(&ddsd2, 0, sizeof(ddsd2));
2594 ddsd2.dwSize = sizeof(ddsd2);
2595 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2596 ddsd2.dwWidth = 64;
2597 ddsd2.dwHeight = 64;
2598 ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2600 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
2601 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
2602 dctest_surf(surf, 1);
2603 IDirectDrawSurface_Release(surf);
2605 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
2606 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2608 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
2609 ok(hr == DD_OK, "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
2610 dctest_surf(surf, 1);
2612 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
2613 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr);
2614 dctest_surf((IDirectDrawSurface *) surf2, 1);
2616 IDirectDrawSurface2_Release(surf2);
2617 IDirectDrawSurface_Release(surf);
2618 IDirectDraw2_Release(dd2);
2620 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
2621 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2623 surf = NULL;
2624 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
2625 ok(hr == DD_OK, "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
2626 dctest_surf((IDirectDrawSurface *) surf4, 2);
2628 hr = IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)&surf);
2629 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
2631 ref = getRefcount((IUnknown *) surf);
2632 ok(ref == 1, "Refcount is %u, expected 1\n", ref);
2633 ref = getRefcount((IUnknown *) surf4);
2634 ok(ref == 1, "Refcount is %u, expected 1\n", ref);
2636 hr = IDirectDrawSurface4_GetDC(surf4, &dc);
2637 ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
2639 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, NULL);
2640 ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
2642 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
2643 ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
2644 ok(tmp == surf, "Expected surface %p, got %p.\n\n", surf, tmp);
2646 ref = getRefcount((IUnknown *) surf);
2647 ok(ref == 2, "Refcount is %u, expected 2\n", ref);
2648 ref = getRefcount((IUnknown *) tmp);
2649 ok(ref == 2, "Refcount is %u, expected 2\n", ref);
2650 ref = getRefcount((IUnknown *) surf4);
2651 ok(ref == 1, "Refcount is %u, expected 1\n", ref);
2653 hr = IDirectDrawSurface4_ReleaseDC(surf4, dc);
2654 ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
2656 IDirectDrawSurface_Release(tmp);
2658 dc = CreateCompatibleDC(NULL);
2659 ok(!!dc, "CreateCompatibleDC failed.\n");
2661 tmp = (IDirectDrawSurface *)0xdeadbeef;
2662 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
2663 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
2664 ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
2666 ok(DeleteDC(dc), "DeleteDC failed.\n");
2668 tmp = (IDirectDrawSurface *)0xdeadbeef;
2669 hr = IDirectDraw4_GetSurfaceFromDC(dd4, NULL, (IDirectDrawSurface4 **)&tmp);
2670 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
2671 ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
2673 IDirectDrawSurface4_Release(surf4);
2674 IDirectDrawSurface_Release(surf);
2675 IDirectDraw4_Release(dd4);
2677 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2678 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2680 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
2681 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
2682 dctest_surf((IDirectDrawSurface *) surf7, 2);
2684 hr = IDirectDrawSurface7_GetDC(surf7, &dc);
2685 ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
2687 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, NULL);
2688 ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
2690 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
2691 ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
2692 ok(tmp7 == surf7, "Expected surface %p, got %p.\n\n", surf7, tmp7);
2693 IDirectDrawSurface7_Release(tmp7);
2695 hr = IDirectDrawSurface7_ReleaseDC(surf7, dc);
2696 ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
2698 dc = CreateCompatibleDC(NULL);
2699 ok(!!dc, "CreateCompatibleDC failed.\n");
2701 tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
2702 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
2703 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
2704 ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
2706 ok(DeleteDC(dc), "DeleteDC failed.\n");
2708 tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
2709 hr = IDirectDraw7_GetSurfaceFromDC(dd7, NULL, (IDirectDrawSurface7 **)&tmp7);
2710 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
2711 ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
2713 IDirectDrawSurface7_Release(surf7);
2714 IDirectDraw7_Release(dd7);
2717 static void GetDCFormatTest(void)
2719 DDSURFACEDESC2 ddsd;
2720 unsigned int i;
2721 IDirectDrawSurface7 *surface;
2722 IDirectDraw7 *dd7;
2723 HRESULT hr;
2724 HDC dc;
2726 struct
2728 const char *name;
2729 DDPIXELFORMAT fmt;
2730 BOOL getdc_capable;
2731 HRESULT alt_result;
2732 } testdata[] = {
2734 "D3DFMT_A8R8G8B8",
2736 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
2737 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
2739 TRUE
2742 "D3DFMT_X8R8G8B8",
2744 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
2745 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
2747 TRUE
2750 "D3DFMT_X8B8G8R8",
2752 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
2753 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
2755 TRUE,
2756 DDERR_CANTCREATEDC /* Vista+ */
2759 "D3DFMT_X8B8G8R8",
2761 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
2762 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}
2764 TRUE,
2765 DDERR_CANTCREATEDC /* Vista+ */
2768 "D3DFMT_A4R4G4B4",
2770 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
2771 {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}
2773 TRUE,
2774 DDERR_CANTCREATEDC /* Vista+ */
2777 "D3DFMT_X4R4G4B4",
2779 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
2780 {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}
2782 TRUE,
2783 DDERR_CANTCREATEDC /* Vista+ */
2786 "D3DFMT_R5G6B5",
2788 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
2789 {16}, {0x0000F800}, {0x000007E0}, {0x0000001F}, {0x00000000}
2791 TRUE
2794 "D3DFMT_A1R5G5B5",
2796 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
2797 {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00008000}
2799 TRUE
2802 "D3DFMT_X1R5G5B5",
2804 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
2805 {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00000000}
2807 TRUE
2810 "D3DFMT_R3G3B2",
2812 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
2813 { 8}, {0x000000E0}, {0x0000001C}, {0x00000003}, {0x00000000}
2815 FALSE
2818 /* Untested, windows test machine didn't support this format */
2819 "D3DFMT_A2R10G10B10",
2821 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
2822 {32}, {0xC0000000}, {0x3FF00000}, {0x000FFC00}, {0x000003FF}
2824 TRUE
2827 * GetDC on a P8 surface fails unless the display mode is 8 bpp. This is not
2828 * implemented in wine yet, so disable the test for now. Succeeding P8 getDC
2829 * calls are tested in the ddraw.visual test.
2832 "D3DFMT_P8",
2834 sizeof(DDPIXELFORMAT), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0,
2835 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
2837 FALSE
2841 "D3DFMT_L8",
2843 sizeof(DDPIXELFORMAT), DDPF_LUMINANCE, 0,
2844 {8 }, {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}
2846 FALSE
2849 "D3DFMT_A8L8",
2851 sizeof(DDPIXELFORMAT), DDPF_ALPHAPIXELS | DDPF_LUMINANCE, 0,
2852 {16}, {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}
2854 FALSE
2857 "D3DFMT_DXT1",
2859 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','1'),
2860 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
2862 FALSE
2865 "D3DFMT_DXT2",
2867 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','2'),
2868 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
2870 FALSE
2873 "D3DFMT_DXT3",
2875 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','3'),
2876 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
2878 FALSE
2881 "D3DFMT_DXT4",
2883 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','4'),
2884 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
2886 FALSE
2889 "D3DFMT_DXT5",
2891 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','5'),
2892 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
2894 FALSE
2898 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2899 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed, hr = 0x%08x\n", hr);
2901 for(i = 0; i < (sizeof(testdata) / sizeof(testdata[0])); i++)
2903 memset(&ddsd, 0, sizeof(ddsd));
2904 ddsd.dwSize = sizeof(ddsd);
2905 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2906 ddsd.dwWidth = 64;
2907 ddsd.dwHeight = 64;
2908 U4(ddsd).ddpfPixelFormat = testdata[i].fmt;
2909 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2911 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2912 if(FAILED(hr))
2914 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2915 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
2916 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2917 if(FAILED(hr))
2919 skip("IDirectDraw7_CreateSurface failed, hr = 0x%08x, format %s\n", hr, testdata[i].name);
2920 continue;
2924 dc = (void *) 0x1234;
2925 hr = IDirectDrawSurface7_GetDC(surface, &dc);
2926 if(testdata[i].getdc_capable)
2928 ok(SUCCEEDED(hr) ||
2929 (testdata[i].alt_result && hr == testdata[i].alt_result),
2930 "GetDC on a %s surface failed(0x%08x), expected it to work\n",
2931 testdata[i].name, hr);
2933 else
2935 ok(FAILED(hr), "GetDC on a %s surface succeeded(0x%08x), expected it to fail\n",
2936 testdata[i].name, hr);
2939 if(SUCCEEDED(hr))
2941 hr = IDirectDrawSurface7_ReleaseDC(surface, dc);
2942 ok(hr == DD_OK, "IDirectDrawSurface7_ReleaseDC failed, hr = 0x%08x\n", hr);
2943 dc = 0;
2945 else
2947 ok(dc == NULL, "After failed GetDC dc is %p\n", dc);
2950 IDirectDrawSurface7_Release(surface);
2953 IDirectDraw7_Release(dd7);
2956 static void BackBufferCreateSurfaceTest(void)
2958 DDSURFACEDESC ddsd;
2959 DDSURFACEDESC created_ddsd;
2960 DDSURFACEDESC2 ddsd2;
2961 IDirectDrawSurface *surf;
2962 IDirectDrawSurface4 *surf4;
2963 IDirectDrawSurface7 *surf7;
2964 HRESULT hr;
2965 IDirectDraw2 *dd2;
2966 IDirectDraw4 *dd4;
2967 IDirectDraw7 *dd7;
2969 const DWORD caps = DDSCAPS_BACKBUFFER;
2970 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
2972 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
2974 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
2975 return ;
2978 memset(&ddsd, 0, sizeof(ddsd));
2979 ddsd.dwSize = sizeof(ddsd);
2980 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2981 ddsd.dwWidth = 64;
2982 ddsd.dwHeight = 64;
2983 ddsd.ddsCaps.dwCaps = caps;
2984 memset(&ddsd2, 0, sizeof(ddsd2));
2985 ddsd2.dwSize = sizeof(ddsd2);
2986 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2987 ddsd2.dwWidth = 64;
2988 ddsd2.dwHeight = 64;
2989 ddsd2.ddsCaps.dwCaps = caps;
2990 memset(&created_ddsd, 0, sizeof(created_ddsd));
2991 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
2993 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
2994 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
2995 if (surf != NULL)
2997 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
2998 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
2999 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3000 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3001 expected_caps);
3002 IDirectDrawSurface_Release(surf);
3005 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3006 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3008 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3009 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3010 DDERR_INVALIDCAPS, hr);
3012 IDirectDraw2_Release(dd2);
3014 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3015 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3017 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3018 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3019 DDERR_INVALIDCAPS, hr);
3021 IDirectDraw4_Release(dd4);
3023 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3024 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3026 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3027 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3028 DDERR_INVALIDCAPS, hr);
3030 IDirectDraw7_Release(dd7);
3033 static void BackBufferAttachmentFlipTest(void)
3035 HRESULT hr;
3036 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3037 DDSURFACEDESC ddsd;
3038 HWND window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
3039 100, 100, 160, 160, NULL, NULL, NULL, NULL);
3041 hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3042 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3044 /* Perform attachment tests on a back-buffer */
3045 memset(&ddsd, 0, sizeof(ddsd));
3046 ddsd.dwSize = sizeof(ddsd);
3047 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3048 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3049 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3050 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3051 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
3052 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3054 if (surface2 != NULL)
3056 /* Try a single primary and a two back buffers */
3057 memset(&ddsd, 0, sizeof(ddsd));
3058 ddsd.dwSize = sizeof(ddsd);
3059 ddsd.dwFlags = DDSD_CAPS;
3060 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3061 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
3062 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3064 memset(&ddsd, 0, sizeof(ddsd));
3065 ddsd.dwSize = sizeof(ddsd);
3066 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3067 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3068 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3069 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3070 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
3071 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3073 /* This one has a different size */
3074 memset(&ddsd, 0, sizeof(ddsd));
3075 ddsd.dwSize = sizeof(ddsd);
3076 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3077 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3078 ddsd.dwWidth = 128;
3079 ddsd.dwHeight = 128;
3080 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
3081 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3083 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3084 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3085 "Attaching a back buffer to a front buffer returned %08x\n", hr);
3086 if(SUCCEEDED(hr))
3088 /* Try flipping the surfaces */
3089 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3090 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3091 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3092 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3094 /* Try the reverse without detaching first */
3095 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3096 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3097 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3098 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3100 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3101 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3102 "Attaching a front buffer to a back buffer returned %08x\n", hr);
3103 if(SUCCEEDED(hr))
3105 /* Try flipping the surfaces */
3106 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3107 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3108 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3109 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3111 /* Try to detach reversed */
3112 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3113 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3114 /* Now the proper detach */
3115 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3116 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3118 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3119 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3120 "Attaching a back buffer to another back buffer returned %08x\n", hr);
3121 if(SUCCEEDED(hr))
3123 /* Try flipping the surfaces */
3124 hr = IDirectDrawSurface_Flip(surface3, NULL, DDFLIP_WAIT);
3125 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3126 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3127 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3128 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3129 ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3131 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3132 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3134 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3135 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3136 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3137 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3139 IDirectDrawSurface_Release(surface4);
3140 IDirectDrawSurface_Release(surface3);
3141 IDirectDrawSurface_Release(surface2);
3142 IDirectDrawSurface_Release(surface1);
3145 hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
3146 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3148 DestroyWindow(window);
3151 static void CreateSurfaceBadCapsSizeTest(void)
3153 DDSURFACEDESC ddsd_ok;
3154 DDSURFACEDESC ddsd_bad1;
3155 DDSURFACEDESC ddsd_bad2;
3156 DDSURFACEDESC ddsd_bad3;
3157 DDSURFACEDESC ddsd_bad4;
3158 DDSURFACEDESC2 ddsd2_ok;
3159 DDSURFACEDESC2 ddsd2_bad1;
3160 DDSURFACEDESC2 ddsd2_bad2;
3161 DDSURFACEDESC2 ddsd2_bad3;
3162 DDSURFACEDESC2 ddsd2_bad4;
3163 IDirectDrawSurface *surf;
3164 IDirectDrawSurface4 *surf4;
3165 IDirectDrawSurface7 *surf7;
3166 HRESULT hr;
3167 IDirectDraw2 *dd2;
3168 IDirectDraw4 *dd4;
3169 IDirectDraw7 *dd7;
3171 const DWORD caps = DDSCAPS_OFFSCREENPLAIN;
3173 memset(&ddsd_ok, 0, sizeof(ddsd_ok));
3174 ddsd_ok.dwSize = sizeof(ddsd_ok);
3175 ddsd_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3176 ddsd_ok.dwWidth = 64;
3177 ddsd_ok.dwHeight = 64;
3178 ddsd_ok.ddsCaps.dwCaps = caps;
3179 ddsd_bad1 = ddsd_ok;
3180 ddsd_bad1.dwSize--;
3181 ddsd_bad2 = ddsd_ok;
3182 ddsd_bad2.dwSize++;
3183 ddsd_bad3 = ddsd_ok;
3184 ddsd_bad3.dwSize = 0;
3185 ddsd_bad4 = ddsd_ok;
3186 ddsd_bad4.dwSize = sizeof(DDSURFACEDESC2);
3188 memset(&ddsd2_ok, 0, sizeof(ddsd2_ok));
3189 ddsd2_ok.dwSize = sizeof(ddsd2_ok);
3190 ddsd2_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3191 ddsd2_ok.dwWidth = 64;
3192 ddsd2_ok.dwHeight = 64;
3193 ddsd2_ok.ddsCaps.dwCaps = caps;
3194 ddsd2_bad1 = ddsd2_ok;
3195 ddsd2_bad1.dwSize--;
3196 ddsd2_bad2 = ddsd2_ok;
3197 ddsd2_bad2.dwSize++;
3198 ddsd2_bad3 = ddsd2_ok;
3199 ddsd2_bad3.dwSize = 0;
3200 ddsd2_bad4 = ddsd2_ok;
3201 ddsd2_bad4.dwSize = sizeof(DDSURFACEDESC);
3203 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_ok, &surf, NULL);
3204 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3205 IDirectDrawSurface_Release(surf);
3207 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad1, &surf, NULL);
3208 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3209 DDERR_INVALIDPARAMS, hr);
3210 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad2, &surf, NULL);
3211 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3212 DDERR_INVALIDPARAMS, hr);
3213 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad3, &surf, NULL);
3214 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3215 DDERR_INVALIDPARAMS, hr);
3216 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad4, &surf, NULL);
3217 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3218 DDERR_INVALIDPARAMS, hr);
3219 hr = IDirectDraw_CreateSurface(lpDD, NULL, &surf, NULL);
3220 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3221 DDERR_INVALIDPARAMS, hr);
3223 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3224 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3226 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_ok, &surf, NULL);
3227 ok(SUCCEEDED(hr), "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
3228 IDirectDrawSurface_Release(surf);
3230 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad1, &surf, NULL);
3231 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3232 DDERR_INVALIDPARAMS, hr);
3233 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad2, &surf, NULL);
3234 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3235 DDERR_INVALIDPARAMS, hr);
3236 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad3, &surf, NULL);
3237 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3238 DDERR_INVALIDPARAMS, hr);
3239 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad4, &surf, NULL);
3240 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3241 DDERR_INVALIDPARAMS, hr);
3242 hr = IDirectDraw2_CreateSurface(dd2, NULL, &surf, NULL);
3243 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3244 DDERR_INVALIDPARAMS, hr);
3246 IDirectDraw2_Release(dd2);
3248 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3249 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3251 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_ok, &surf4, NULL);
3252 ok(SUCCEEDED(hr), "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
3253 IDirectDrawSurface4_Release(surf4);
3255 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad1, &surf4, NULL);
3256 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3257 DDERR_INVALIDPARAMS, hr);
3258 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad2, &surf4, NULL);
3259 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3260 DDERR_INVALIDPARAMS, hr);
3261 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad3, &surf4, NULL);
3262 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3263 DDERR_INVALIDPARAMS, hr);
3264 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad4, &surf4, NULL);
3265 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3266 DDERR_INVALIDPARAMS, hr);
3267 hr = IDirectDraw4_CreateSurface(dd4, NULL, &surf4, NULL);
3268 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3269 DDERR_INVALIDPARAMS, hr);
3271 IDirectDraw4_Release(dd4);
3273 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3274 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3276 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_ok, &surf7, NULL);
3277 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
3278 IDirectDrawSurface7_Release(surf7);
3280 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad1, &surf7, NULL);
3281 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3282 DDERR_INVALIDPARAMS, hr);
3283 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad2, &surf7, NULL);
3284 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3285 DDERR_INVALIDPARAMS, hr);
3286 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad3, &surf7, NULL);
3287 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3288 DDERR_INVALIDPARAMS, hr);
3289 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad4, &surf7, NULL);
3290 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3291 DDERR_INVALIDPARAMS, hr);
3292 hr = IDirectDraw7_CreateSurface(dd7, NULL, &surf7, NULL);
3293 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3294 DDERR_INVALIDPARAMS, hr);
3296 IDirectDraw7_Release(dd7);
3299 static void reset_ddsd(DDSURFACEDESC *ddsd)
3301 memset(ddsd, 0, sizeof(*ddsd));
3302 ddsd->dwSize = sizeof(*ddsd);
3305 static void no_ddsd_caps_test(void)
3307 DDSURFACEDESC ddsd;
3308 HRESULT hr;
3309 IDirectDrawSurface *surface;
3311 reset_ddsd(&ddsd);
3312 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
3313 ddsd.dwWidth = 128;
3314 ddsd.dwHeight = 128;
3315 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3316 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3317 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
3318 reset_ddsd(&ddsd);
3319 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
3320 IDirectDrawSurface_Release(surface);
3321 ok(ddsd.dwFlags & DDSD_CAPS, "DDSD_CAPS is not set\n");
3322 ok(ddsd.ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN, "DDSCAPS_OFFSCREENPLAIN is not set\n");
3324 reset_ddsd(&ddsd);
3325 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3326 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3327 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
3328 reset_ddsd(&ddsd);
3329 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
3330 IDirectDrawSurface_Release(surface);
3331 ok(ddsd.dwFlags & DDSD_CAPS, "DDSD_CAPS is not set\n");
3332 ok(ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE, "DDSCAPS_OFFSCREENPLAIN is not set\n");
3334 reset_ddsd(&ddsd);
3335 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
3336 ddsd.dwWidth = 128;
3337 ddsd.dwHeight = 128;
3338 ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
3339 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3340 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw_CreateSurface returned %#x, expected DDERR_INVALIDCAPS.\n", hr);
3343 static void dump_format(const DDPIXELFORMAT *fmt)
3345 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %u\n", fmt->dwFlags, fmt->dwFourCC,
3346 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
3347 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
3348 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
3351 static void zbufferbitdepth_test(void)
3353 enum zfmt_succeed
3355 ZFMT_SUPPORTED_ALWAYS,
3356 ZFMT_SUPPORTED_NEVER,
3357 ZFMT_SUPPORTED_HWDEPENDENT
3359 struct
3361 DWORD depth;
3362 enum zfmt_succeed supported;
3363 DDPIXELFORMAT pf;
3365 test_data[] =
3368 16, ZFMT_SUPPORTED_ALWAYS,
3370 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3371 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
3375 24, ZFMT_SUPPORTED_HWDEPENDENT,
3377 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3378 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
3382 32, ZFMT_SUPPORTED_HWDEPENDENT,
3384 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3385 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
3388 /* Returns DDERR_INVALIDPARAMS instead of DDERR_INVALIDPIXELFORMAT.
3389 * Disabled for now
3391 0, ZFMT_SUPPORTED_NEVER
3395 15, ZFMT_SUPPORTED_NEVER
3398 28, ZFMT_SUPPORTED_NEVER
3401 40, ZFMT_SUPPORTED_NEVER
3405 DDSURFACEDESC ddsd;
3406 IDirectDrawSurface *surface;
3407 HRESULT hr;
3408 unsigned int i;
3409 DDCAPS caps;
3411 memset(&caps, 0, sizeof(caps));
3412 caps.dwSize = sizeof(caps);
3413 hr = IDirectDraw_GetCaps(lpDD, &caps, NULL);
3414 ok(SUCCEEDED(hr), "IDirectDraw_GetCaps failed, hr %#x.\n", hr);
3415 if (!(caps.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
3417 skip("Z buffers not supported, skipping DDSD_ZBUFFERBITDEPTH test\n");
3418 return;
3421 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
3423 reset_ddsd(&ddsd);
3424 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH;
3425 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
3426 ddsd.dwWidth = 256;
3427 ddsd.dwHeight = 256;
3428 U2(ddsd).dwZBufferBitDepth = test_data[i].depth;
3430 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3431 if (test_data[i].supported == ZFMT_SUPPORTED_ALWAYS)
3433 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
3435 else if (test_data[i].supported == ZFMT_SUPPORTED_NEVER)
3437 ok(hr == DDERR_INVALIDPIXELFORMAT, "IDirectDraw_CreateSurface returned %#x, expected %x.\n",
3438 hr, DDERR_INVALIDPIXELFORMAT);
3440 if (!surface) continue;
3442 reset_ddsd(&ddsd);
3443 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
3444 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
3445 IDirectDrawSurface_Release(surface);
3447 ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
3448 ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
3449 /* Yet the ddpfPixelFormat member contains valid data */
3450 if (memcmp(&ddsd.ddpfPixelFormat, &test_data[i].pf, ddsd.ddpfPixelFormat.dwSize))
3452 ok(0, "Unexpected format for depth %u\n", test_data[i].depth);
3453 dump_format(&ddsd.ddpfPixelFormat);
3457 /* DDSD_ZBUFFERBITDEPTH vs DDSD_PIXELFORMAT? */
3458 reset_ddsd(&ddsd);
3459 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_ZBUFFERBITDEPTH;
3460 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
3461 ddsd.dwWidth = 256;
3462 ddsd.dwHeight = 256;
3463 U2(ddsd).dwZBufferBitDepth = 24;
3464 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
3465 ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3466 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth = 16;
3467 U3(ddsd.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
3469 surface = NULL;
3470 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3471 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
3472 if (!surface) return;
3473 reset_ddsd(&ddsd);
3474 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
3475 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
3476 IDirectDrawSurface_Release(surface);
3477 ok(U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth == 16, "Expected a 16bpp depth buffer, got %ubpp\n",
3478 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth);
3479 ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
3480 ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
3481 ok(U2(ddsd).dwZBufferBitDepth == 16, "Expected dwZBufferBitDepth=16, got %u\n",
3482 U2(ddsd).dwZBufferBitDepth);
3484 /* DDSD_PIXELFORMAT vs invalid ZBUFFERBITDEPTH */
3485 reset_ddsd(&ddsd);
3486 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_PIXELFORMAT;
3487 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
3488 ddsd.dwWidth = 256;
3489 ddsd.dwHeight = 256;
3490 U2(ddsd).dwZBufferBitDepth = 40;
3491 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
3492 ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3493 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth = 16;
3494 U3(ddsd.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
3495 surface = NULL;
3496 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3497 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
3498 if (surface) IDirectDrawSurface_Release(surface);
3500 /* Create a PIXELFORMAT-only surface, see if ZBUFFERBITDEPTH is set */
3501 reset_ddsd(&ddsd);
3502 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
3503 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
3504 ddsd.dwWidth = 256;
3505 ddsd.dwHeight = 256;
3506 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
3507 ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3508 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth = 16;
3509 U3(ddsd.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
3510 surface = NULL;
3511 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3512 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
3513 reset_ddsd(&ddsd);
3514 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
3515 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
3516 IDirectDrawSurface_Release(surface);
3517 ok(U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth == 16, "Expected a 16bpp depth buffer, got %ubpp\n",
3518 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth);
3519 ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
3520 ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
3521 ok(U2(ddsd).dwZBufferBitDepth == 16, "Expected dwZBufferBitDepth=16, got %u\n",
3522 U2(ddsd).dwZBufferBitDepth);
3525 static void test_ddsd(DDSURFACEDESC *ddsd, BOOL expect_pf, BOOL expect_zd, const char *name, DWORD z_bit_depth)
3527 IDirectDrawSurface *surface;
3528 IDirectDrawSurface7 *surface7;
3529 HRESULT hr;
3530 DDSURFACEDESC out;
3531 DDSURFACEDESC2 out2;
3533 hr = IDirectDraw_CreateSurface(lpDD, ddsd, &surface, NULL);
3534 if (hr == DDERR_NOZBUFFERHW)
3536 skip("Z buffers not supported, skipping Z flag test\n");
3537 return;
3539 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
3540 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **) &surface7);
3541 ok(SUCCEEDED(hr), "IDirectDrawSurface_QueryInterface failed, hr %#x.\n", hr);
3543 reset_ddsd(&out);
3544 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &out);
3545 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
3546 memset(&out2, 0, sizeof(out2));
3547 out2.dwSize = sizeof(out2);
3548 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &out2);
3549 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
3551 if (expect_pf)
3553 ok(out.dwFlags & DDSD_PIXELFORMAT, "%s surface: Expected DDSD_PIXELFORMAT to be set\n", name);
3554 ok(out2.dwFlags & DDSD_PIXELFORMAT,
3555 "%s surface: Expected DDSD_PIXELFORMAT to be set in DDSURFACEDESC2\n", name);
3557 else
3559 ok(!(out.dwFlags & DDSD_PIXELFORMAT), "%s surface: Expected DDSD_PIXELFORMAT not to be set\n", name);
3560 ok(out2.dwFlags & DDSD_PIXELFORMAT,
3561 "%s surface: Expected DDSD_PIXELFORMAT to be set in DDSURFACEDESC2\n", name);
3563 if (expect_zd)
3565 ok(out.dwFlags & DDSD_ZBUFFERBITDEPTH, "%s surface: Expected DDSD_ZBUFFERBITDEPTH to be set\n", name);
3566 ok(U2(out).dwZBufferBitDepth == z_bit_depth, "ZBufferBitDepth is %u, expected %u\n",
3567 U2(out).dwZBufferBitDepth, z_bit_depth);
3568 ok(!(out2.dwFlags & DDSD_ZBUFFERBITDEPTH),
3569 "%s surface: Did not expect DDSD_ZBUFFERBITDEPTH to be set in DDSURFACEDESC2\n", name);
3570 /* dwMipMapCount and dwZBufferBitDepth share the same union */
3571 ok(U2(out2).dwMipMapCount == 0, "dwMipMapCount is %u, expected 0\n", U2(out2).dwMipMapCount);
3573 else
3575 ok(!(out.dwFlags & DDSD_ZBUFFERBITDEPTH), "%s surface: Expected DDSD_ZBUFFERBITDEPTH not to be set\n", name);
3576 ok(U2(out).dwZBufferBitDepth == 0, "ZBufferBitDepth is %u, expected 0\n", U2(out).dwZBufferBitDepth);
3577 ok(!(out2.dwFlags & DDSD_ZBUFFERBITDEPTH),
3578 "%s surface: Did not expect DDSD_ZBUFFERBITDEPTH to be set in DDSURFACEDESC2\n", name);
3579 ok(U2(out2).dwMipMapCount == 0, "dwMipMapCount is %u, expected 0\n", U2(out2).dwMipMapCount);
3582 reset_ddsd(&out);
3583 hr = IDirectDrawSurface_Lock(surface, NULL, &out, 0, NULL);
3584 if (SUCCEEDED(hr))
3586 hr = IDirectDrawSurface_Unlock(surface, NULL);
3587 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
3589 /* DDSD_ZBUFFERBITDEPTH is never set on Nvidia, but follows GetSurfaceDesc rules on AMD */
3590 if (!expect_zd)
3592 ok(!(out.dwFlags & DDSD_ZBUFFERBITDEPTH),
3593 "Lock %s surface: Expected DDSD_ZBUFFERBITDEPTH not to be set\n", name);
3596 /* DDSD_PIXELFORMAT follows GetSurfaceDesc rules */
3597 if (expect_pf)
3599 ok(out.dwFlags & DDSD_PIXELFORMAT, "%s surface: Expected DDSD_PIXELFORMAT to be set\n", name);
3601 else
3603 ok(!(out.dwFlags & DDSD_PIXELFORMAT),
3604 "Lock %s surface: Expected DDSD_PIXELFORMAT not to be set\n", name);
3606 if (out.dwFlags & DDSD_ZBUFFERBITDEPTH)
3607 ok(U2(out).dwZBufferBitDepth == z_bit_depth, "ZBufferBitDepth is %u, expected %u\n",
3608 U2(out).dwZBufferBitDepth, z_bit_depth);
3609 else
3610 ok(U2(out).dwZBufferBitDepth == 0, "ZBufferBitDepth is %u, expected 0\n", U2(out).dwZBufferBitDepth);
3613 hr = IDirectDrawSurface7_Lock(surface7, NULL, &out2, 0, NULL);
3614 ok(SUCCEEDED(hr), "IDirectDrawSurface7_Lock failed, hr %#x.\n", hr);
3615 if (SUCCEEDED(hr))
3617 hr = IDirectDrawSurface7_Unlock(surface7, NULL);
3618 ok(SUCCEEDED(hr), "IDirectDrawSurface7_Unlock failed, hr %#x.\n", hr);
3619 /* DDSD_PIXELFORMAT is always set, DDSD_ZBUFFERBITDEPTH never */
3620 ok(out2.dwFlags & DDSD_PIXELFORMAT,
3621 "Lock %s surface: Expected DDSD_PIXELFORMAT to be set in DDSURFACEDESC2\n", name);
3622 ok(!(out2.dwFlags & DDSD_ZBUFFERBITDEPTH),
3623 "Lock %s surface: Did not expect DDSD_ZBUFFERBITDEPTH to be set in DDSURFACEDESC2\n", name);
3624 ok(U2(out2).dwMipMapCount == 0, "dwMipMapCount is %u, expected 0\n", U2(out2).dwMipMapCount);
3627 IDirectDrawSurface7_Release(surface7);
3628 IDirectDrawSurface_Release(surface);
3631 static void pixelformat_flag_test(void)
3633 DDSURFACEDESC ddsd;
3634 DDCAPS caps;
3635 HRESULT hr;
3637 memset(&caps, 0, sizeof(caps));
3638 caps.dwSize = sizeof(caps);
3639 hr = IDirectDraw_GetCaps(lpDD, &caps, NULL);
3640 ok(SUCCEEDED(hr), "IDirectDraw_GetCaps failed, hr %#x.\n", hr);
3641 if (!(caps.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
3643 skip("Z buffers not supported, skipping DDSD_PIXELFORMAT test\n");
3644 return;
3647 reset_ddsd(&ddsd);
3648 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3649 ddsd.dwWidth = 64;
3650 ddsd.dwHeight = 64;
3651 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3652 test_ddsd(&ddsd, TRUE, FALSE, "offscreen plain", ~0U);
3654 reset_ddsd(&ddsd);
3655 ddsd.dwFlags = DDSD_CAPS;
3656 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3657 test_ddsd(&ddsd, TRUE, FALSE, "primary", ~0U);
3659 reset_ddsd(&ddsd);
3660 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_ZBUFFERBITDEPTH;
3661 ddsd.dwWidth = 64;
3662 ddsd.dwHeight = 64;
3663 U2(ddsd).dwZBufferBitDepth = 16;
3664 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
3665 test_ddsd(&ddsd, FALSE, TRUE, "Z buffer", 16);
3668 static BOOL fourcc_supported(DWORD fourcc, DWORD caps)
3670 DDSURFACEDESC ddsd;
3671 HRESULT hr;
3672 IDirectDrawSurface *surface;
3674 reset_ddsd(&ddsd);
3675 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
3676 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
3677 ddsd.dwWidth = 4;
3678 ddsd.dwHeight = 4;
3679 ddsd.ddsCaps.dwCaps = caps;
3680 ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
3681 ddsd.ddpfPixelFormat.dwFourCC = fourcc;
3682 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3683 if (FAILED(hr))
3685 return FALSE;
3687 IDirectDrawSurface_Release(surface);
3688 return TRUE;
3691 static void partial_block_lock_test(void)
3693 IDirectDrawSurface7 *surface;
3694 HRESULT hr;
3695 DDSURFACEDESC2 ddsd;
3696 IDirectDraw7 *dd7;
3697 const struct
3699 DWORD caps, caps2;
3700 const char *name;
3701 BOOL success;
3703 pools[] =
3706 DDSCAPS_VIDEOMEMORY, 0,
3707 "D3DPOOL_DEFAULT", FALSE
3710 DDSCAPS_SYSTEMMEMORY, 0,
3711 "D3DPOOL_SYSTEMMEM", TRUE
3714 0, DDSCAPS2_TEXTUREMANAGE,
3715 "D3DPOOL_MANAGED", TRUE
3718 const struct
3720 DWORD fourcc;
3721 DWORD caps;
3722 const char *name;
3723 unsigned int block_width;
3724 unsigned int block_height;
3726 formats[] =
3728 {MAKEFOURCC('D','X','T','1'), DDSCAPS_TEXTURE, "D3DFMT_DXT1", 4, 4},
3729 {MAKEFOURCC('D','X','T','2'), DDSCAPS_TEXTURE, "D3DFMT_DXT2", 4, 4},
3730 {MAKEFOURCC('D','X','T','3'), DDSCAPS_TEXTURE, "D3DFMT_DXT3", 4, 4},
3731 {MAKEFOURCC('D','X','T','4'), DDSCAPS_TEXTURE, "D3DFMT_DXT4", 4, 4},
3732 {MAKEFOURCC('D','X','T','5'), DDSCAPS_TEXTURE, "D3DFMT_DXT5", 4, 4},
3733 /* ATI2N surfaces aren't available in ddraw */
3734 {MAKEFOURCC('U','Y','V','Y'), DDSCAPS_OVERLAY, "D3DFMT_UYVY", 2, 1},
3735 {MAKEFOURCC('Y','U','Y','2'), DDSCAPS_OVERLAY, "D3DFMT_YUY2", 2, 1},
3737 unsigned int i, j;
3738 RECT rect;
3740 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3741 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3743 for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
3745 if (!fourcc_supported(formats[i].fourcc, formats[i].caps | DDSCAPS_VIDEOMEMORY))
3747 skip("%s surfaces not supported, skipping partial block lock test\n", formats[i].name);
3748 continue;
3751 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); j++)
3753 if (formats[i].caps & DDSCAPS_OVERLAY && !(pools[j].caps & DDSCAPS_VIDEOMEMORY))
3754 continue;
3756 memset(&ddsd, 0, sizeof(ddsd));
3757 ddsd.dwSize = sizeof(ddsd);
3758 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
3759 ddsd.dwWidth = 128;
3760 ddsd.dwHeight = 128;
3761 ddsd.ddsCaps.dwCaps = pools[j].caps | formats[i].caps;
3762 ddsd.ddsCaps.dwCaps2 = pools[j].caps2;
3763 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
3764 U4(ddsd).ddpfPixelFormat.dwFourCC = formats[i].fourcc;
3765 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3766 ok(SUCCEEDED(hr), "CreateSurface failed, hr %#x, format %s, pool %s\n",
3767 hr, formats[i].name, pools[j].name);
3769 /* All Windows versions allow partial block locks with DDSCAPS_SYSTEMMEMORY and
3770 * DDSCAPS2_TEXTUREMANAGE, just like in d3d8 and d3d9. Windows XP also allows those locks
3771 * with DDSCAPS_VIDEOMEMORY. Windows Vista and Windows 7 disallow partial locks of vidmem
3772 * surfaces, making the ddraw behavior consistent with d3d8 and 9.
3774 * Mark the Windows XP behavior as broken until we find an application that needs it */
3775 if (formats[i].block_width > 1)
3777 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
3778 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3779 ok(SUCCEEDED(hr) == pools[j].success || broken(SUCCEEDED(hr)),
3780 "Partial block lock %s, expected %s, format %s, pool %s\n",
3781 SUCCEEDED(hr) ? "succeeded" : "failed", pools[j].success ? "success" : "failure",
3782 formats[i].name, pools[j].name);
3783 if (SUCCEEDED(hr))
3785 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3786 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3789 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
3790 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3791 ok(SUCCEEDED(hr) == pools[j].success || broken(SUCCEEDED(hr)),
3792 "Partial block lock %s, expected %s, format %s, pool %s\n",
3793 SUCCEEDED(hr) ? "succeeded" : "failed", pools[j].success ? "success" : "failure",
3794 formats[i].name, pools[j].name);
3795 if (SUCCEEDED(hr))
3797 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3798 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3802 if (formats[i].block_height > 1)
3804 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
3805 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3806 ok(SUCCEEDED(hr) == pools[j].success || broken(SUCCEEDED(hr)),
3807 "Partial block lock %s, expected %s, format %s, pool %s\n",
3808 SUCCEEDED(hr) ? "succeeded" : "failed", pools[j].success ? "success" : "failure",
3809 formats[i].name, pools[j].name);
3810 if (SUCCEEDED(hr))
3812 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3813 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3816 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
3817 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3818 ok(SUCCEEDED(hr) == pools[j].success || broken(SUCCEEDED(hr)),
3819 "Partial block lock %s, expected %s, format %s, pool %s\n",
3820 SUCCEEDED(hr) ? "succeeded" : "failed", pools[j].success ? "success" : "failure",
3821 formats[i].name, pools[j].name);
3822 if (SUCCEEDED(hr))
3824 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3825 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3829 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
3830 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3831 ok(SUCCEEDED(hr), "Full block lock returned %08x, expected %08x, format %s, pool %s\n",
3832 hr, DD_OK, formats[i].name, pools[j].name);
3833 if (SUCCEEDED(hr))
3835 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3836 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3839 IDirectDrawSurface7_Release(surface);
3843 IDirectDraw7_Release(dd7);
3846 static void create_surface_test(void)
3848 HRESULT hr;
3849 IDirectDraw2 *ddraw2;
3850 IDirectDraw4 *ddraw4;
3851 IDirectDraw7 *ddraw7;
3852 IDirectDrawSurface *surface;
3853 IDirectDrawSurface4 *surface4;
3854 IDirectDrawSurface7 *surface7;
3856 hr = IDirectDraw_CreateSurface(lpDD, NULL, &surface, NULL);
3857 ok(hr == DDERR_INVALIDPARAMS, "CreateSurface(ddsd=NULL) returned %#x,"
3858 " expected %#x.\n", hr, DDERR_INVALIDPARAMS);
3860 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &ddraw2);
3861 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3863 hr = IDirectDraw2_CreateSurface(ddraw2, NULL, &surface, NULL);
3864 ok(hr == DDERR_INVALIDPARAMS, "CreateSurface(ddsd=NULL) returned %#x,"
3865 " expected %#x.\n", hr, DDERR_INVALIDPARAMS);
3867 IDirectDraw2_Release(ddraw2);
3869 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &ddraw4);
3870 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3872 hr = IDirectDraw4_CreateSurface(ddraw4, NULL, &surface4, NULL);
3873 ok(hr == DDERR_INVALIDPARAMS, "CreateSurface(ddsd=NULL) returned %#x,"
3874 " expected %#x.\n", hr, DDERR_INVALIDPARAMS);
3876 IDirectDraw4_Release(ddraw4);
3878 if (!pDirectDrawCreateEx)
3880 skip("DirectDrawCreateEx not available, skipping IDirectDraw7 tests.\n");
3881 return;
3883 hr = pDirectDrawCreateEx(NULL, (void **) &ddraw7, &IID_IDirectDraw7, NULL);
3884 ok(SUCCEEDED(hr), "DirectDrawCreateEx failed, hr %#x.\n", hr);
3886 hr = IDirectDraw7_CreateSurface(ddraw7, NULL, &surface7, NULL);
3887 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "CreateSurface(ddsd=NULL, pre-SCL) returned %#x,"
3888 " expected %#x.\n", hr, DDERR_NOCOOPERATIVELEVELSET);
3890 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, NULL, DDSCL_NORMAL);
3891 ok(hr == DD_OK, "SetCooperativeLevel failed, hr %#x.\n", hr);
3893 hr = IDirectDraw7_CreateSurface(ddraw7, NULL, &surface7, NULL);
3894 ok(hr == DDERR_INVALIDPARAMS, "CreateSurface(ddsd=NULL) returned %#x,"
3895 " expected %#x.\n", hr, DDERR_INVALIDPARAMS);
3897 IDirectDraw7_Release(ddraw7);
3900 START_TEST(dsurface)
3902 HRESULT ret;
3903 IDirectDraw4 *dd4;
3905 HMODULE ddraw_mod = GetModuleHandleA("ddraw.dll");
3906 pDirectDrawCreateEx = (void *) GetProcAddress(ddraw_mod, "DirectDrawCreateEx");
3908 if (!CreateDirectDraw())
3909 return;
3911 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3912 if (ret == E_NOINTERFACE)
3914 win_skip("DirectDraw4 and higher are not supported\n");
3915 ReleaseDirectDraw();
3916 return;
3918 IDirectDraw_Release(dd4);
3920 if(!can_create_primary_surface())
3922 skip("Unable to create primary surface\n");
3923 return;
3926 ddcaps.dwSize = sizeof(DDCAPS);
3927 ret = IDirectDraw_GetCaps(lpDD, &ddcaps, NULL);
3928 if (ret != DD_OK)
3930 skip("IDirectDraw_GetCaps failed with %08x\n", ret);
3931 return;
3934 MipMapCreationTest();
3935 SrcColorKey32BlitTest();
3936 QueryInterface();
3937 GetDDInterface_1();
3938 GetDDInterface_2();
3939 GetDDInterface_4();
3940 GetDDInterface_7();
3941 EnumTest();
3942 CubeMapTest();
3943 test_lockrect_invalid();
3944 CompressedTest();
3945 SizeTest();
3946 BltParamTest();
3947 StructSizeTest();
3948 PaletteTest();
3949 SurfaceCapsTest();
3950 GetDCTest();
3951 GetDCFormatTest();
3952 BackBufferCreateSurfaceTest();
3953 BackBufferAttachmentFlipTest();
3954 CreateSurfaceBadCapsSizeTest();
3955 no_ddsd_caps_test();
3956 zbufferbitdepth_test();
3957 pixelformat_flag_test();
3958 partial_block_lock_test();
3959 create_surface_test();
3960 ReleaseDirectDraw();