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