ole32: Fix memory leaks in the storage test.
[wine] / dlls / ddraw / tests / dsurface.c
1 /*
2  * Unit tests for (a few) ddraw surface functions
3  *
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
9  *
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.
14  *
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.
19  *
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
23  */
24 #define COBJMACROS
25
26 #include <assert.h>
27 #include "wine/test.h"
28 #include "ddraw.h"
29 #include "d3d.h"
30 #include "unknwn.h"
31
32 static LPDIRECTDRAW lpDD = NULL;
33
34 static BOOL CreateDirectDraw(void)
35 {
36     HRESULT rc;
37
38     rc = DirectDrawCreate(NULL, &lpDD, NULL);
39     ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
40     if (!lpDD) {
41         trace("DirectDrawCreateEx() failed with an error %x\n", rc);
42         return FALSE;
43     }
44
45     rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
46     ok(rc==DD_OK,"SetCooperativeLevel returned: %x\n",rc);
47
48     return TRUE;
49 }
50
51
52 static void ReleaseDirectDraw(void)
53 {
54     if( lpDD != NULL )
55     {
56         IDirectDraw_Release(lpDD);
57         lpDD = NULL;
58     }
59 }
60
61 static void MipMapCreationTest(void)
62 {
63     LPDIRECTDRAWSURFACE lpDDSMipMapTest;
64     DDSURFACEDESC ddsd;
65     HRESULT rc;
66
67     /* First mipmap creation test: create a surface with DDSCAPS_COMPLEX,
68        DDSCAPS_MIPMAP, and DDSD_MIPMAPCOUNT. This create the number of
69         requested mipmap levels. */
70     ddsd.dwSize = sizeof(ddsd);
71     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
72     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
73     U2(ddsd).dwMipMapCount = 3;
74     ddsd.dwWidth = 128;
75     ddsd.dwHeight = 32;
76     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
77     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
78     if (FAILED(rc)) {
79         skip("failed to create surface\n");
80         return;
81     }
82
83     /* Check the number of created mipmaps */
84     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
85     ddsd.dwSize = sizeof(ddsd);
86     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
87     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
88     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
89         "GetSurfaceDesc returned no mipmapcount.\n");
90     ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %d.\n",
91         U2(ddsd).dwMipMapCount);
92
93     /* Destroy the surface. */
94     IDirectDrawSurface_Release(lpDDSMipMapTest);
95
96
97     /* Second mipmap creation test: create a surface without a mipmap
98        count, with DDSCAPS_MIPMAP and without DDSCAPS_COMPLEX.
99        This creates a single mipmap level. */
100     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
101     ddsd.dwSize = sizeof(ddsd);
102     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
103     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
104     ddsd.dwWidth = 128;
105     ddsd.dwHeight = 32;
106     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
107     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
108     if (FAILED(rc)) {
109         skip("failed to create surface\n");
110         return;
111     }
112     /* Check the number of created mipmaps */
113     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
114     ddsd.dwSize = sizeof(ddsd);
115     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
116     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
117     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
118         "GetSurfaceDesc returned no mipmapcount.\n");
119     ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %d.\n",
120         U2(ddsd).dwMipMapCount);
121
122     /* Destroy the surface. */
123     IDirectDrawSurface_Release(lpDDSMipMapTest);
124
125
126     /* Third mipmap creation test: create a surface with DDSCAPS_MIPMAP,
127         DDSCAPS_COMPLEX and without DDSD_MIPMAPCOUNT.
128        It's an undocumented features where a chain of mipmaps, starting from
129        he specified size and down to the smallest size, is automatically
130        created.
131        Anarchy Online needs this feature to work. */
132     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
133     ddsd.dwSize = sizeof(ddsd);
134     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
135     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
136     ddsd.dwWidth = 128;
137     ddsd.dwHeight = 32;
138     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
139     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
140     if (FAILED(rc)) {
141         skip("failed to create surface\n");
142         return;
143     }
144
145     /* Check the number of created mipmaps */
146     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
147     ddsd.dwSize = sizeof(ddsd);
148     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
149     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
150     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
151         "GetSurfaceDesc returned no mipmapcount.\n");
152     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
153         U2(ddsd).dwMipMapCount);
154
155     /* Destroy the surface. */
156     IDirectDrawSurface_Release(lpDDSMipMapTest);
157
158
159     /* Fourth mipmap creation test: same as above with a different texture
160        size.
161        The purpose is to verify that the number of generated mipmaps is
162        dependent on the smallest dimension. */
163     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
164     ddsd.dwSize = sizeof(ddsd);
165     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
166     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
167     ddsd.dwWidth = 32;
168     ddsd.dwHeight = 64;
169     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
170     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
171     if (FAILED(rc)) {
172         skip("failed to create surface\n");
173         return;
174     }
175
176     /* Check the number of created mipmaps */
177     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
178     ddsd.dwSize = sizeof(ddsd);
179     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
180     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
181     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
182         "GetSurfaceDesc returned no mipmapcount.\n");
183     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
184         U2(ddsd).dwMipMapCount);
185
186     /* Destroy the surface. */
187     IDirectDrawSurface_Release(lpDDSMipMapTest);
188
189
190     /* Fifth mipmap creation test: try to create a surface with
191        DDSCAPS_COMPLEX, DDSCAPS_MIPMAP, DDSD_MIPMAPCOUNT,
192        where dwMipMapCount = 0. This should fail. */
193
194     ddsd.dwSize = sizeof(ddsd);
195     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
196     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
197     U2(ddsd).dwMipMapCount = 0;
198     ddsd.dwWidth = 128;
199     ddsd.dwHeight = 32;
200     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
201     ok(rc==DDERR_INVALIDPARAMS,"CreateSurface returned: %x\n",rc);
202
203     /* Destroy the surface. */
204     if( rc == DD_OK )
205         IDirectDrawSurface_Release(lpDDSMipMapTest);
206
207 }
208
209 static void SrcColorKey32BlitTest(void)
210 {
211     LPDIRECTDRAWSURFACE lpSrc;
212     LPDIRECTDRAWSURFACE lpDst;
213     DDSURFACEDESC ddsd, ddsd2, ddsd3;
214     DDCOLORKEY DDColorKey;
215     LPDWORD lpData;
216     HRESULT rc;
217     DDBLTFX fx;
218
219     ddsd2.dwSize = sizeof(ddsd2);
220     ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
221
222     ddsd.dwSize = sizeof(ddsd);
223     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
224     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
225     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
226     ddsd.dwWidth = 800;
227     ddsd.dwHeight = 600;
228     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
229     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
230     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
231     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
232     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
233     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
234     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
235     if (FAILED(rc)) {
236         skip("failed to create surface\n");
237         return;
238     }
239
240     ddsd.dwFlags |= DDSD_CKSRCBLT;
241     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
242     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
243     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
244     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
245     if (FAILED(rc)) {
246         skip("failed to create surface\n");
247         return;
248     }
249
250     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
251     ok(rc==DD_OK,"Lock returned: %x\n",rc);
252     lpData = ddsd2.lpSurface;
253     lpData[0] = 0xCCCCCCCC;
254     lpData[1] = 0xCCCCCCCC;
255     lpData[2] = 0xCCCCCCCC;
256     lpData[3] = 0xCCCCCCCC;
257
258     memset(&ddsd3, 0, sizeof(ddsd3));
259     ddsd3.dwSize = sizeof(ddsd3);
260     ddsd3.ddpfPixelFormat.dwSize = sizeof(ddsd3.ddpfPixelFormat);
261     rc = IDirectDrawSurface_GetSurfaceDesc(lpDst, &ddsd3);
262     ok(rc == DD_OK, "IDirectDrawSurface_GetSurfaceDesc between a lock/unlock pair returned %08x\n", rc);
263     ok(ddsd3.lpSurface == ddsd3.lpSurface, "lpSurface from GetSurfaceDesc(%p) differs from the one returned by Lock(%p)\n", ddsd3.lpSurface, ddsd2.lpSurface);
264
265     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
266     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
267
268     memset(&ddsd3, 0, sizeof(ddsd3));
269     ddsd3.dwSize = sizeof(ddsd3);
270     ddsd3.ddpfPixelFormat.dwSize = sizeof(ddsd3.ddpfPixelFormat);
271     rc = IDirectDrawSurface_GetSurfaceDesc(lpDst, &ddsd3);
272     ok(rc == DD_OK, "IDirectDrawSurface_GetSurfaceDesc between a lock/unlock pair returned %08x\n", rc);
273     ok(ddsd3.lpSurface == NULL, "lpSurface from GetSurfaceDesc(%p) is not NULL after unlock\n", ddsd3.lpSurface);
274
275     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
276     ok(rc==DD_OK,"Lock returned: %x\n",rc);
277     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
278     lpData = ddsd2.lpSurface;
279     lpData[0] = 0x77010203;
280     lpData[1] = 0x00010203;
281     lpData[2] = 0x77FF00FF;
282     lpData[3] = 0x00FF00FF;
283     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
284     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
285
286     IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
287
288     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
289     ok(rc==DD_OK,"Lock returned: %x\n",rc);
290     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
291     lpData = ddsd2.lpSurface;
292     /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
293      * color keying, but copy it to the destination surface. Others apply it for color keying, but
294      * do not copy it into the destination surface.
295      */
296     if(lpData[0]==0x00010203) {
297         trace("X channel was not copied into the destination surface\n");
298         ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
299            "Destination data after blitting is not correct\n");
300     } else {
301         ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
302            "Destination data after blitting is not correct\n");
303     }
304     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
305     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
306
307     /* Below we repeat the same test as above but now using BltFast instead of Blt. Before
308      * we can carry out the test we need to restore the color of the destination surface.
309      */
310     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
311     ok(rc==DD_OK,"Lock returned: %x\n",rc);
312     lpData = ddsd2.lpSurface;
313     lpData[0] = 0xCCCCCCCC;
314     lpData[1] = 0xCCCCCCCC;
315     lpData[2] = 0xCCCCCCCC;
316     lpData[3] = 0xCCCCCCCC;
317     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
318     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
319
320     IDirectDrawSurface_BltFast(lpDst, 0, 0, lpSrc, NULL, DDBLTFAST_SRCCOLORKEY);
321
322     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
323     ok(rc==DD_OK,"Lock returned: %x\n",rc);
324     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
325     lpData = ddsd2.lpSurface;
326     /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
327      * color keying, but copy it to the destination surface. Others apply it for color keying, but
328      * do not copy it into the destination surface.
329      */
330     if(lpData[0]==0x00010203) {
331         trace("X channel was not copied into the destination surface\n");
332         ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
333            "Destination data after blitting is not correct\n");
334     } else {
335         ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
336            "Destination data after blitting is not correct\n");
337     }
338     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
339     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
340
341     /* Also test SetColorKey */
342     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
343     ok(DDColorKey.dwColorSpaceLowValue == 0xFF00FF && DDColorKey.dwColorSpaceHighValue == 0xFF00FF,
344        "GetColorKey does not return the colorkey used at surface creation\n");
345
346     DDColorKey.dwColorSpaceLowValue = 0x00FF00;
347     DDColorKey.dwColorSpaceHighValue = 0x00FF00;
348     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
349
350     DDColorKey.dwColorSpaceLowValue = 0;
351     DDColorKey.dwColorSpaceHighValue = 0;
352     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
353     ok(DDColorKey.dwColorSpaceLowValue == 0x00FF00 && DDColorKey.dwColorSpaceHighValue == 0x00FF00,
354        "GetColorKey does not return the colorkey set with SetColorKey\n");
355
356     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
357     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
358     IDirectDrawSurface_GetSurfaceDesc(lpSrc, &ddsd);
359     ok(ddsd.ddckCKSrcBlt.dwColorSpaceLowValue == 0x00FF00 && ddsd.ddckCKSrcBlt.dwColorSpaceHighValue == 0x00FF00,
360        "GetSurfaceDesc does not return the colorkey set with SetColorKey\n");
361
362     /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
363     DDColorKey.dwColorSpaceLowValue = 0x0000FF;
364     DDColorKey.dwColorSpaceHighValue = 0x000000;
365     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
366
367     DDColorKey.dwColorSpaceLowValue = 0;
368     DDColorKey.dwColorSpaceHighValue = 0;
369     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
370     ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
371        "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
372
373     DDColorKey.dwColorSpaceLowValue = 0x0000FF;
374     DDColorKey.dwColorSpaceHighValue = 0x000001;
375     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
376
377     DDColorKey.dwColorSpaceLowValue = 0;
378     DDColorKey.dwColorSpaceHighValue = 0;
379     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
380     ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
381        "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
382
383     DDColorKey.dwColorSpaceLowValue = 0x0000FF;
384     DDColorKey.dwColorSpaceHighValue = 0x0000FE;
385     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
386
387     DDColorKey.dwColorSpaceLowValue = 0;
388     DDColorKey.dwColorSpaceHighValue = 0;
389     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
390     ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
391        "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
392
393     IDirectDrawSurface_Release(lpSrc);
394     IDirectDrawSurface_Release(lpDst);
395
396     /* start with a new set of surfaces to test the color keying parameters to blit */
397     memset(&ddsd, 0, sizeof(ddsd));
398     ddsd.dwSize = sizeof(ddsd);
399     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
400     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
401     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
402     ddsd.dwWidth = 800;
403     ddsd.dwHeight = 600;
404     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
405     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
406     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
407     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
408     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
409     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0xFF0000;
410     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0xFF0000;
411     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x00FF00;
412     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x00FF00;
413     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
414     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
415     if(FAILED(rc))
416     {
417         skip("Failed to create surface\n");
418         return;
419     }
420
421     /* start with a new set of surfaces to test the color keying parameters to blit */
422     memset(&ddsd, 0, sizeof(ddsd));
423     ddsd.dwSize = sizeof(ddsd);
424     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
425     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
426     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
427     ddsd.dwWidth = 800;
428     ddsd.dwHeight = 600;
429     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
430     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
431     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
432     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
433     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
434     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x0000FF;
435     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x0000FF;
436     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0x000000;
437     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0x000000;
438     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
439     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
440     if(FAILED(rc))
441     {
442         skip("Failed to create surface\n");
443         IDirectDrawSurface_Release(lpDst);
444         return;
445     }
446
447     memset(&fx, 0, sizeof(fx));
448     fx.dwSize = sizeof(fx);
449     fx.ddckSrcColorkey.dwColorSpaceHighValue = 0x110000;
450     fx.ddckSrcColorkey.dwColorSpaceLowValue = 0x110000;
451     fx.ddckDestColorkey.dwColorSpaceHighValue = 0x001100;
452     fx.ddckDestColorkey.dwColorSpaceLowValue = 0x001100;
453
454     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
455     ok(rc==DD_OK,"Lock returned: %x\n",rc);
456     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
457     lpData = ddsd2.lpSurface;
458     lpData[0] = 0x000000FF; /* Applies to src blt key in src surface */
459     lpData[1] = 0x00000000; /* Applies to dst blt key in src surface */
460     lpData[2] = 0x00FF0000; /* Dst color key in dst surface */
461     lpData[3] = 0x0000FF00; /* Src color key in dst surface */
462     lpData[4] = 0x00001100; /* Src color key in ddbltfx */
463     lpData[5] = 0x00110000; /* Dst color key in ddbltfx */
464     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
465     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
466
467     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
468     ok(rc==DD_OK,"Lock returned: %x\n",rc);
469     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
470     lpData = ddsd2.lpSurface;
471     lpData[0] = 0x55555555;
472     lpData[1] = 0x55555555;
473     lpData[2] = 0x55555555;
474     lpData[3] = 0x55555555;
475     lpData[4] = 0x55555555;
476     lpData[5] = 0x55555555;
477     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
478     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
479
480     /* Test a blit without keying */
481     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, 0, &fx);
482     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
483
484     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
485     ok(rc==DD_OK,"Lock returned: %x\n",rc);
486     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
487     lpData = ddsd2.lpSurface;
488     /* Should have copied src data unmodified to dst */
489     ok(lpData[0] == 0x000000FF &&
490        lpData[1] == 0x00000000 &&
491        lpData[2] == 0x00FF0000 &&
492        lpData[3] == 0x0000FF00 &&
493        lpData[4] == 0x00001100 &&
494        lpData[5] == 0x00110000, "Surface data after unkeyed blit does not match\n");
495
496     lpData[0] = 0x55555555;
497     lpData[1] = 0x55555555;
498     lpData[2] = 0x55555555;
499     lpData[3] = 0x55555555;
500     lpData[4] = 0x55555555;
501     lpData[5] = 0x55555555;
502     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
503     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
504
505     /* Src key */
506     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
507     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
508
509     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
510     ok(rc==DD_OK,"Lock returned: %x\n",rc);
511     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
512     lpData = ddsd2.lpSurface;
513
514     ok(lpData[0] == 0x55555555 && /* Here the src key applied */
515        lpData[1] == 0x00000000 &&
516        lpData[2] == 0x00FF0000 &&
517        lpData[3] == 0x0000FF00 &&
518        lpData[4] == 0x00001100 &&
519        lpData[5] == 0x00110000, "Surface data after srckey blit does not match\n");
520
521     lpData[0] = 0x55555555;
522     lpData[1] = 0x55555555;
523     lpData[2] = 0x55555555;
524     lpData[3] = 0x55555555;
525     lpData[4] = 0x55555555;
526     lpData[5] = 0x55555555;
527     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
528     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
529
530     /* Src override */
531     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
532     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
533
534     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
535     ok(rc==DD_OK,"Lock returned: %x\n",rc);
536     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
537     lpData = ddsd2.lpSurface;
538
539     ok(lpData[0] == 0x000000FF &&
540        lpData[1] == 0x00000000 &&
541        lpData[2] == 0x00FF0000 &&
542        lpData[3] == 0x0000FF00 &&
543        lpData[4] == 0x00001100 &&
544        lpData[5] == 0x55555555, /* Override key applies here */
545        "Surface data after src override key blit does not match\n");
546
547     lpData[0] = 0x55555555;
548     lpData[1] = 0x55555555;
549     lpData[2] = 0x55555555;
550     lpData[3] = 0x55555555;
551     lpData[4] = 0x55555555;
552     lpData[5] = 0x55555555;
553     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
554     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
555
556     /* Src override AND src key. That is not supposed to work */
557     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &fx);
558     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
559
560     /* Verify that the destination is unchanged */
561     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
562     ok(rc==DD_OK,"Lock returned: %x\n",rc);
563     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
564     lpData = ddsd2.lpSurface;
565
566     ok(lpData[0] == 0x55555555 &&
567        lpData[1] == 0x55555555 &&
568        lpData[2] == 0x55555555 &&
569        lpData[3] == 0x55555555 &&
570        lpData[4] == 0x55555555 &&
571        lpData[5] == 0x55555555, /* Override key applies here */
572        "Surface data after src key blit with override does not match\n");
573
574     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
575     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
576     lpData[2] = 0x00001100; /* Dest key in override */
577     lpData[3] = 0x00001100; /* Dest key in override */
578     lpData[4] = 0x00000000; /* Dest key in src surface */
579     lpData[5] = 0x00000000; /* Dest key in src surface */
580     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
581     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
582
583     /* Dest key blit */
584     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
585     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
586
587     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
588     ok(rc==DD_OK,"Lock returned: %x\n",rc);
589     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
590     lpData = ddsd2.lpSurface;
591
592     /* DirectDraw uses the dest blit key from the SOURCE surface ! */
593     ok(lpData[0] == 0x00ff0000 &&
594        lpData[1] == 0x00ff0000 &&
595        lpData[2] == 0x00001100 &&
596        lpData[3] == 0x00001100 &&
597        lpData[4] == 0x00001100 && /* Key applies here */
598        lpData[5] == 0x00110000,   /* Key applies here */
599        "Surface data after dest key blit does not match\n");
600
601     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
602     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
603     lpData[2] = 0x00001100; /* Dest key in override */
604     lpData[3] = 0x00001100; /* Dest key in override */
605     lpData[4] = 0x00000000; /* Dest key in src surface */
606     lpData[5] = 0x00000000; /* Dest key in src surface */
607     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
608     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
609
610     /* Dest override key blit */
611     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
612     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
613
614     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
615     ok(rc==DD_OK,"Lock returned: %x\n",rc);
616     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
617     lpData = ddsd2.lpSurface;
618
619     ok(lpData[0] == 0x00FF0000 &&
620        lpData[1] == 0x00FF0000 &&
621        lpData[2] == 0x00FF0000 && /* Key applies here */
622        lpData[3] == 0x0000FF00 && /* Key applies here */
623        lpData[4] == 0x00000000 &&
624        lpData[5] == 0x00000000,
625        "Surface data after dest key override blit does not match\n");
626
627     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
628     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
629     lpData[2] = 0x00001100; /* Dest key in override */
630     lpData[3] = 0x00001100; /* Dest key in override */
631     lpData[4] = 0x00000000; /* Dest key in src surface */
632     lpData[5] = 0x00000000; /* Dest key in src surface */
633     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
634     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
635
636     /* Dest override key blit. Supposed to fail too */
637     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYDESTOVERRIDE, &fx);
638     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
639
640     /* Check for unchanged data */
641     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
642     ok(rc==DD_OK,"Lock returned: %x\n",rc);
643     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
644     lpData = ddsd2.lpSurface;
645
646     ok(lpData[0] == 0x00FF0000 &&
647        lpData[1] == 0x00FF0000 &&
648        lpData[2] == 0x00001100 && /* Key applies here */
649        lpData[3] == 0x00001100 && /* Key applies here */
650        lpData[4] == 0x00000000 &&
651        lpData[5] == 0x00000000,
652        "Surface data with dest key and dest override does not match\n");
653
654     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
655     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
656     lpData[2] = 0x00001100; /* Dest key in override */
657     lpData[3] = 0x00001100; /* Dest key in override */
658     lpData[4] = 0x00000000; /* Dest key in src surface */
659     lpData[5] = 0x00000000; /* Dest key in src surface */
660     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
661     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
662
663     /* Modify the source data a bit to give some more conclusive results */
664     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
665     ok(rc==DD_OK,"Lock returned: %x\n",rc);
666     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
667     lpData = ddsd2.lpSurface;
668     lpData[5] = 0x000000FF; /* Applies to src blt key in src surface */
669     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
670     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
671
672     /* Source and destination key */
673     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYSRC, &fx);
674     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
675
676     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
677     ok(rc==DD_OK,"Lock returned: %x\n",rc);
678     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
679     lpData = ddsd2.lpSurface;
680
681     ok(lpData[0] == 0x00FF0000 && /* Masked by Destination key */
682        lpData[1] == 0x00FF0000 && /* Masked by Destination key */
683        lpData[2] == 0x00001100 && /* Masked by Destination key */
684        lpData[3] == 0x00001100 && /* Masked by Destination key */
685        lpData[4] == 0x00001100 && /* Allowed by destination key, not masked by source key */
686        lpData[5] == 0x00000000,   /* Allowed by dst key, but masked by source key */
687        "Surface data with src key and dest key blit does not match\n");
688
689     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
690     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
691     lpData[2] = 0x00001100; /* Dest key in override */
692     lpData[3] = 0x00001100; /* Dest key in override */
693     lpData[4] = 0x00000000; /* Dest key in src surface */
694     lpData[5] = 0x00000000; /* Dest key in src surface */
695     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
696     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
697
698     /* Override keys without ddbltfx parameter fail */
699     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, NULL);
700     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
701     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, NULL);
702     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
703
704     /* Try blitting without keys in the source surface*/
705     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, NULL);
706     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
707     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_DESTBLT, NULL);
708     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
709
710     /* That fails now. Do not bother to check that the data is unmodified */
711     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
712     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
713
714     /* Dest key blit still works. Which key is used this time??? */
715     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
716     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
717
718     /* With correctly passed override keys no key in the surface is needed.
719      * Again, the result was checked before, no need to do that again
720      */
721     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
722     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
723     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
724     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
725
726     IDirectDrawSurface_Release(lpSrc);
727     IDirectDrawSurface_Release(lpDst);
728 }
729
730 static void QueryInterface(void)
731 {
732     LPDIRECTDRAWSURFACE dsurface;
733     DDSURFACEDESC surface;
734     LPVOID object;
735     HRESULT ret;
736
737     /* Create a surface */
738     ZeroMemory(&surface, sizeof(surface));
739     surface.dwSize = sizeof(surface);
740     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
741     surface.dwHeight = 10;
742     surface.dwWidth = 10;
743     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
744     if(ret != DD_OK)
745     {
746         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
747         return;
748     }
749
750     /* Call IUnknown::QueryInterface */
751     ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
752     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %x\n", ret);
753
754     IDirectDrawSurface_Release(dsurface);
755 }
756
757 /* The following tests test which interface is returned by IDirectDrawSurfaceX::GetDDInterface.
758  * It uses refcounts to test that and compares the interface addresses. Partially fits here, and
759  * partially in the refcount test
760  */
761
762 static ULONG getref(IUnknown *iface)
763 {
764     IUnknown_AddRef(iface);
765     return IUnknown_Release(iface);
766 }
767
768 static void GetDDInterface_1(void)
769 {
770     LPDIRECTDRAWSURFACE dsurface;
771     LPDIRECTDRAWSURFACE2 dsurface2;
772     DDSURFACEDESC surface;
773     HRESULT ret;
774     IDirectDraw2 *dd2;
775     IDirectDraw4 *dd4;
776     IDirectDraw7 *dd7;
777     ULONG ref1, ref2, ref4, ref7;
778     void *dd;
779
780     /* Create a surface */
781     ZeroMemory(&surface, sizeof(surface));
782     surface.dwSize = sizeof(surface);
783     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
784     surface.dwHeight = 10;
785     surface.dwWidth = 10;
786     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
787     if(ret != DD_OK)
788     {
789         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
790         return;
791     }
792     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
793     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
794     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
795     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
796     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
797     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
798     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
799     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
800
801     ref1 = getref((IUnknown *) lpDD);
802     ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
803     ref2 = getref((IUnknown *) dd2);
804     ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
805     ref4 = getref((IUnknown *) dd4);
806     ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
807     ref7 = getref((IUnknown *) dd7);
808     ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
809
810
811     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
812     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
813     ok(getref((IUnknown *) lpDD) == ref1 + 1, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
814     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
815     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
816     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
817
818     ok(dd == lpDD, "Returned interface pointer is not equal to the creation interface\n");
819     IUnknown_Release((IUnknown *) dd);
820
821     /* try a NULL pointer */
822     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, NULL);
823     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
824
825     IDirectDraw_Release(dd2);
826     IDirectDraw_Release(dd4);
827     IDirectDraw_Release(dd7);
828     IDirectDrawSurface2_Release(dsurface2);
829     IDirectDrawSurface_Release(dsurface);
830 }
831
832 static void GetDDInterface_2(void)
833 {
834     LPDIRECTDRAWSURFACE dsurface;
835     LPDIRECTDRAWSURFACE2 dsurface2;
836     DDSURFACEDESC surface;
837     HRESULT ret;
838     IDirectDraw2 *dd2;
839     IDirectDraw4 *dd4;
840     IDirectDraw7 *dd7;
841     ULONG ref1, ref2, ref4, ref7;
842     void *dd;
843
844     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
845     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
846     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
847     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
848     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
849     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
850
851     /* Create a surface */
852     ZeroMemory(&surface, sizeof(surface));
853     surface.dwSize = sizeof(surface);
854     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
855     surface.dwHeight = 10;
856     surface.dwWidth = 10;
857     ret = IDirectDraw2_CreateSurface(dd2, &surface, &dsurface, NULL);
858     if(ret != DD_OK)
859     {
860         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
861         return;
862     }
863     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
864     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
865
866     ref1 = getref((IUnknown *) lpDD);
867     ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
868     ref2 = getref((IUnknown *) dd2);
869     ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
870     ref4 = getref((IUnknown *) dd4);
871     ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
872     ref7 = getref((IUnknown *) dd7);
873     ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
874
875
876     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
877     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
878     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
879     ok(getref((IUnknown *) dd2) == ref2 + 1, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
880     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
881     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
882
883     ok(dd == dd2, "Returned interface pointer is not equal to the creation interface\n");
884     IUnknown_Release((IUnknown *) dd);
885
886     IDirectDraw_Release(dd2);
887     IDirectDraw_Release(dd4);
888     IDirectDraw_Release(dd7);
889     IDirectDrawSurface2_Release(dsurface2);
890     IDirectDrawSurface_Release(dsurface);
891 }
892
893 static void GetDDInterface_4(void)
894 {
895     LPDIRECTDRAWSURFACE2 dsurface2;
896     LPDIRECTDRAWSURFACE4 dsurface4;
897     DDSURFACEDESC2 surface;
898     HRESULT ret;
899     IDirectDraw2 *dd2;
900     IDirectDraw4 *dd4;
901     IDirectDraw7 *dd7;
902     ULONG ref1, ref2, ref4, ref7;
903     void *dd;
904
905     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
906     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
907     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
908     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
909     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
910     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
911
912     /* Create a surface */
913     ZeroMemory(&surface, sizeof(surface));
914     surface.dwSize = sizeof(surface);
915     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
916     surface.dwHeight = 10;
917     surface.dwWidth = 10;
918     ret = IDirectDraw4_CreateSurface(dd4, &surface, &dsurface4, NULL);
919     if(ret != DD_OK)
920     {
921         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
922         return;
923     }
924     ret = IDirectDrawSurface4_QueryInterface(dsurface4, &IID_IDirectDrawSurface2, (void **) &dsurface2);
925     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
926
927     ref1 = getref((IUnknown *) lpDD);
928     ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
929     ref2 = getref((IUnknown *) dd2);
930     ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
931     ref4 = getref((IUnknown *) dd4);
932     ok(ref4 == 2, "IDirectDraw4 refcount is %d\n", ref4);
933     ref7 = getref((IUnknown *) dd7);
934     ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
935
936     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
937     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
938     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
939     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
940     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
941     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
942
943     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
944     IUnknown_Release((IUnknown *) dd);
945
946     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
947     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
948     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
949     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
950     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
951     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
952     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
953
954     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
955     IUnknown_Release((IUnknown *) dd);
956
957     IDirectDraw_Release(dd2);
958     IDirectDraw_Release(dd4);
959     IDirectDraw_Release(dd7);
960     IDirectDrawSurface4_Release(dsurface4);
961     IDirectDrawSurface2_Release(dsurface2);
962 }
963
964 static void GetDDInterface_7(void)
965 {
966     LPDIRECTDRAWSURFACE4 dsurface4;
967     LPDIRECTDRAWSURFACE7 dsurface7;
968     DDSURFACEDESC2 surface;
969     HRESULT ret;
970     IDirectDraw2 *dd2;
971     IDirectDraw4 *dd4;
972     IDirectDraw7 *dd7;
973     ULONG ref1, ref2, ref4, ref7;
974     void *dd;
975
976     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
977     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
978     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
979     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
980     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
981     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
982
983     /* Create a surface */
984     ZeroMemory(&surface, sizeof(surface));
985     surface.dwSize = sizeof(surface);
986     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
987     surface.dwHeight = 10;
988     surface.dwWidth = 10;
989     ret = IDirectDraw7_CreateSurface(dd7, &surface, &dsurface7, NULL);
990     if(ret != DD_OK)
991     {
992         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
993         return;
994     }
995     ret = IDirectDrawSurface7_QueryInterface(dsurface7, &IID_IDirectDrawSurface4, (void **) &dsurface4);
996     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
997
998     ref1 = getref((IUnknown *) lpDD);
999     ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
1000     ref2 = getref((IUnknown *) dd2);
1001     ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
1002     ref4 = getref((IUnknown *) dd4);
1003     ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
1004     ref7 = getref((IUnknown *) dd7);
1005     ok(ref7 == 2, "IDirectDraw7 refcount is %d\n", ref7);
1006
1007     ret = IDirectDrawSurface7_GetDDInterface(dsurface7, &dd);
1008     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1009     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1010     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1011     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1012     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1013
1014     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1015     IUnknown_Release((IUnknown *) dd);
1016
1017     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
1018     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
1019     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1020     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1021     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1022     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1023     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1024
1025     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1026     IUnknown_Release((IUnknown *) dd);
1027
1028     IDirectDraw_Release(dd2);
1029     IDirectDraw_Release(dd4);
1030     IDirectDraw_Release(dd7);
1031     IDirectDrawSurface4_Release(dsurface4);
1032     IDirectDrawSurface7_Release(dsurface7);
1033 }
1034
1035 static ULONG getRefcount(IUnknown *iface)
1036 {
1037     IUnknown_AddRef(iface);
1038     return IUnknown_Release(iface);
1039 }
1040
1041 static void IFaceRefCount(void)
1042 {
1043     LPDIRECTDRAWSURFACE surf;
1044     DDSURFACEDESC surface;
1045     HRESULT ret;
1046     IDirectDrawSurface2 *surf2;
1047     IDirectDrawSurface2 *surf2a;
1048     IDirectDrawSurface4 *surf4;
1049     IDirectDrawSurface7 *surf7a;
1050     IDirectDrawSurface7 *surf7b;
1051     IDirect3DTexture* tex;
1052     IDirect3DTexture2* tex2;
1053     IDirectDrawGammaControl* gamma;
1054     ULONG ref;
1055
1056     /* Create a surface */
1057     ZeroMemory(&surface, sizeof(surface));
1058     surface.dwSize = sizeof(surface);
1059     surface.dwFlags = DDSD_CAPS;
1060     surface.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1061     ret = IDirectDraw_CreateSurface(lpDD, &surface, &surf, NULL);
1062
1063     if (ret != DD_OK)
1064     {
1065         ok(FALSE, "Could not create surface, skipping test\n");
1066         return;
1067     }
1068
1069     ref = getRefcount((IUnknown *) surf);
1070     ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
1071
1072     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
1073     ref = getRefcount((IUnknown *) surf);
1074     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
1075     ref = getRefcount((IUnknown *) surf2);
1076     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* This should also be one */
1077
1078     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2a);
1079     ref = getRefcount((IUnknown *) surf2);
1080     todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);   /* Surf2's refcount should be 2 now, but surf should be 1 */
1081     ref = getRefcount((IUnknown *) surf);
1082     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1083
1084     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface4, (void **) &surf4);
1085     ref = getRefcount((IUnknown *) surf4);
1086     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1087
1088     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7a);
1089     ref = getRefcount((IUnknown *) surf7a);
1090     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1091
1092     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7b);
1093     ref = getRefcount((IUnknown *) surf7b);
1094     todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1095
1096     /* IDirect3DTexture interface (unlike the others) alters the original IDirectDrawSurface ref count */
1097     ret = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture, (void **) &tex);
1098     if (SUCCEEDED(ret))
1099     {
1100         ref = getRefcount((IUnknown *) tex);
1101         todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1102         ref = getRefcount((IUnknown *) surf);
1103         todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1104
1105         IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture2, (void **) &tex2);
1106         ref = getRefcount((IUnknown *) tex);
1107         todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1108         ref = getRefcount((IUnknown *) tex2);
1109         todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1110         ref = getRefcount((IUnknown *) surf);
1111         todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1112
1113         IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawGammaControl, (void **) &gamma);
1114         ref = getRefcount((IUnknown *) gamma);
1115         todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1116
1117         ref = IDirect3DTexture2_Release(tex2); /* Release the texture */
1118         todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1119         ref = getRefcount((IUnknown *) surf);
1120         todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1121
1122         ref = IDirect3DTexture_Release(tex); /* Release the texture */
1123         todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1124         ref = getRefcount((IUnknown *) surf);
1125         todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1126
1127         ref = IDirectDrawGammaControl_Release(gamma); /* Release the gamma control */
1128         todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1129     }
1130
1131     ref = IDirectDrawSurface2_Release(surf2); /* Release one of the 2 surf2 interfaces */
1132     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1133
1134     ref = IDirectDrawSurface2_Release(surf2a); /* Release the other */
1135     todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1136
1137     ref = IDirectDrawSurface4_Release(surf4);
1138     todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1139
1140     ref = IDirectDrawSurface7_Release(surf7a);
1141     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1142
1143     ref = IDirectDrawSurface7_Release(surf7b);
1144     todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1145
1146     ref = IDirectDrawSurface_Release(surf);
1147     ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1148 }
1149
1150 #define MAXEXPECTED 8  /* Can match up to 8 expected surfaces */
1151 struct enumstruct
1152 {
1153     IDirectDrawSurface *expected[MAXEXPECTED];
1154     UINT count;
1155 };
1156
1157 static HRESULT WINAPI enumCB(IDirectDrawSurface *surf, DDSURFACEDESC *desc, void *ctx)
1158 {
1159     int i;
1160     BOOL found = FALSE;
1161
1162     for(i = 0; i < MAXEXPECTED; i++)
1163     {
1164         if(((struct enumstruct *)ctx)->expected[i] == surf) found = TRUE;
1165     }
1166
1167     ok(found, "Unexpected surface %p enumerated\n", surf);
1168     ((struct enumstruct *)ctx)->count++;
1169     IDirectDrawSurface_Release(surf);
1170     return DDENUMRET_OK;
1171 }
1172
1173 static void EnumTest(void)
1174 {
1175     HRESULT rc;
1176     DDSURFACEDESC ddsd;
1177     IDirectDrawSurface *surface;
1178     struct enumstruct ctx;
1179
1180     ddsd.dwSize = sizeof(ddsd);
1181     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1182     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1183     U2(ddsd).dwMipMapCount = 3;
1184     ddsd.dwWidth = 32;
1185     ddsd.dwHeight = 32;
1186     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
1187     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
1188
1189     memset(&ctx, 0, sizeof(ctx));
1190     ctx.expected[0] = surface;
1191     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[0], &ddsd.ddsCaps, &ctx.expected[1]);
1192     ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1193     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[1], &ddsd.ddsCaps, &ctx.expected[2]);
1194     ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1195     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[2], &ddsd.ddsCaps, &ctx.expected[3]);
1196     ok(rc == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", rc);
1197     ok(!ctx.expected[3], "expected NULL pointer\n");
1198     ctx.count = 0;
1199
1200     rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, &ddsd, &ctx, enumCB);
1201     ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
1202     ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
1203
1204     IDirectDrawSurface_Release(ctx.expected[2]);
1205     IDirectDrawSurface_Release(ctx.expected[1]);
1206     IDirectDrawSurface_Release(surface);
1207 }
1208
1209 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1210 {
1211     UINT *num = context;
1212     (*num)++;
1213     IDirectDrawSurface_Release(surface);
1214     return DDENUMRET_OK;
1215 }
1216
1217 static void AttachmentTest7(void)
1218 {
1219     HRESULT hr;
1220     IDirectDraw7 *dd7;
1221     IDirectDrawSurface7 *surface1, *surface2, *surface3, *surface4;
1222     DDSURFACEDESC2 ddsd, ddsd2;
1223     UINT num;
1224     DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0}, caps2 = {DDSCAPS_BACKBUFFER,0,0,0};
1225     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1226
1227     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1228     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1229
1230     memset(&ddsd, 0, sizeof(ddsd));
1231     ddsd.dwSize = sizeof(ddsd);
1232     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1233     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1234     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1235     ddsd.dwWidth = 128;
1236     ddsd.dwHeight = 128;
1237     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1238     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1239
1240     /* ROOT */
1241     num = 0;
1242     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1243     ok(num == 1, "Mipmap root has %d surfaces attached, expected 1\n", num);
1244     /* DONE ROOT */
1245
1246     /* LEVEL 1 */
1247     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1248     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1249     num = 0;
1250     IDirectDrawSurface7_EnumAttachedSurfaces(surface2, &num, SurfaceCounter);
1251     ok(num == 1, "First mip level has %d surfaces attached, expected 1\n", num);
1252     /* DONE LEVEL 1 */
1253
1254     /* LEVEL 2 */
1255     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1256     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1257     IDirectDrawSurface7_Release(surface2);
1258     num = 0;
1259     IDirectDrawSurface7_EnumAttachedSurfaces(surface3, &num, SurfaceCounter);
1260     ok(num == 0, "Second mip level has %d surfaces attached, expected 1\n", num);
1261     /* Done level 2 */
1262     /* Mip level 3 is still needed */
1263     hr = IDirectDrawSurface7_GetAttachedSurface(surface3, &caps, &surface4);
1264     ok(hr == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", hr);
1265     ok(!surface4, "expected NULL pointer\n");
1266
1267     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1268     memset(&ddsd, 0, sizeof(ddsd));
1269     ddsd.dwSize = sizeof(ddsd);
1270     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1271     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1272     ddsd.dwWidth = 16;
1273     ddsd.dwHeight = 16;
1274     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1275     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1276
1277     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1278     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1279     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1280     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1281     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1282     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1283     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1284     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1285
1286     IDirectDrawSurface7_Release(surface2);
1287
1288     memset(&ddsd, 0, sizeof(ddsd));
1289     ddsd.dwSize = sizeof(ddsd);
1290     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1291     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1292     ddsd.dwWidth = 16;
1293     ddsd.dwHeight = 16;
1294     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1295     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1296
1297     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1298     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1299     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1300     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1301     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1302     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1303     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1304     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1305
1306     IDirectDrawSurface7_Release(surface3);
1307     IDirectDrawSurface7_Release(surface2);
1308     IDirectDrawSurface7_Release(surface1);
1309
1310     hr = IDirectDraw7_SetCooperativeLevel(dd7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1311     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1312
1313     memset(&ddsd, 0, sizeof(ddsd));
1314     ddsd.dwSize = sizeof(ddsd);
1315     ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
1316     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
1317     ddsd.dwBackBufferCount = 2;
1318     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1319     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1320
1321     /* backbuffer surfaces must not have dwBackBufferCount set */
1322     ddsd2.dwSize = sizeof(ddsd2);
1323     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps2, &surface2);
1324     ok(hr==DD_OK,"GetAttachedSurface returned: %x\n", hr);
1325     hr = IDirectDrawSurface7_GetSurfaceDesc(surface2, &ddsd2);
1326     ok(hr==DD_OK,"GetSurfaceDesc returned: %x\n", hr);
1327     ok(ddsd2.dwBackBufferCount==0,"backbuffer surface has dwBackBufferCount==%u\n", ddsd2.dwBackBufferCount);
1328
1329     num = 0;
1330     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1331     ok(num == 1, "Primary surface has %d surfaces attached, expected 1\n", num);
1332     IDirectDrawSurface7_Release(surface1);
1333
1334     /* Those are some invalid descriptions, no need to test attachments with them */
1335     memset(&ddsd, 0, sizeof(ddsd));
1336     ddsd.dwSize = sizeof(ddsd);
1337     ddsd.dwFlags = DDSD_CAPS;
1338     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1339     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1340     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1341     memset(&ddsd, 0, sizeof(ddsd));
1342     ddsd.dwSize = sizeof(ddsd);
1343     ddsd.dwFlags = DDSD_CAPS;
1344     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1345     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1346     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1347
1348     /* Try a single primary and two offscreen plain surfaces */
1349     memset(&ddsd, 0, sizeof(ddsd));
1350     ddsd.dwSize = sizeof(ddsd);
1351     ddsd.dwFlags = DDSD_CAPS;
1352     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1353     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1354     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1355
1356     memset(&ddsd, 0, sizeof(ddsd));
1357     ddsd.dwSize = sizeof(ddsd);
1358     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1359     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1360     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1361     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1362     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1363     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1364
1365     memset(&ddsd, 0, sizeof(ddsd));
1366     ddsd.dwSize = sizeof(ddsd);
1367     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1368     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1369     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1370     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1371     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface3, NULL);
1372     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1373
1374     /* This one has a different size */
1375     memset(&ddsd, 0, sizeof(ddsd));
1376     ddsd.dwSize = sizeof(ddsd);
1377     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1378     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1379     ddsd.dwWidth = 128;
1380     ddsd.dwHeight = 128;
1381     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface4, NULL);
1382     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1383
1384     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1385     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1386     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1387     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1388     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1389     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1390     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1391     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1392     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1393     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1394
1395     IDirectDrawSurface7_Release(surface4);
1396     IDirectDrawSurface7_Release(surface3);
1397     IDirectDrawSurface7_Release(surface2);
1398     IDirectDrawSurface7_Release(surface1);
1399
1400     hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL);
1401     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1402     IDirectDraw7_Release(dd7);
1403 }
1404
1405 static void AttachmentTest(void)
1406 {
1407     HRESULT hr;
1408     IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
1409     DDSURFACEDESC ddsd;
1410     DDSCAPS caps = {DDSCAPS_TEXTURE};
1411     BOOL refrast = FALSE;
1412     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1413
1414     memset(&ddsd, 0, sizeof(ddsd));
1415     ddsd.dwSize = sizeof(ddsd);
1416     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1417     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1418     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1419     ddsd.dwWidth = 128;
1420     ddsd.dwHeight = 128;
1421     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1422     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1423
1424     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1425     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1426     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1427     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1428
1429     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1430     memset(&ddsd, 0, sizeof(ddsd));
1431     ddsd.dwSize = sizeof(ddsd);
1432     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1433     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1434     ddsd.dwWidth = 16;
1435     ddsd.dwHeight = 16;
1436     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1437     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1438
1439     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1440     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1441     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1442     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1443     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
1444     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1445     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1446     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1447     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
1448     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 64x64 texture sublevel returned %08x\n", hr);
1449     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1450     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 texture returned %08x\n", hr);
1451
1452     IDirectDrawSurface7_Release(surface4);
1453
1454     memset(&ddsd, 0, sizeof(ddsd));
1455     ddsd.dwSize = sizeof(ddsd);
1456     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1457     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1458     ddsd.dwWidth = 16;
1459     ddsd.dwHeight = 16;
1460     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1461     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1462
1463     if (SUCCEEDED(IDirectDrawSurface7_AddAttachedSurface(surface1, surface4)))
1464     {
1465         IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1466         refrast = TRUE;
1467     }
1468
1469     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4); /* Succeeds on refrast */
1470     if (refrast)
1471         ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1472     else
1473         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1474     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1475
1476     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);  /* Succeeds on refrast */
1477     if (refrast)
1478         ok(hr == S_OK, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1479     else
1480         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1481     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface1);
1482
1483     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);  /* Succeeds on refrast */
1484     if (refrast)
1485         ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1486     else
1487         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1488     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface3, 0, surface4);
1489
1490     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1491     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1492     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface3);
1493
1494     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);  /* Succeeds on refrast */
1495     if (refrast)
1496         ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1497     else
1498         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1499     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface2, 0, surface4);
1500
1501     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1502     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 offscreen plain surface returned %08x\n", hr);
1503     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface2);
1504
1505     IDirectDrawSurface7_Release(surface4);
1506     IDirectDrawSurface7_Release(surface3);
1507     IDirectDrawSurface7_Release(surface2);
1508     IDirectDrawSurface7_Release(surface1);
1509
1510     hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1511     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1512
1513     /* Creating a back buffer as-is, is not allowed. No need to perform attachment tests */
1514     memset(&ddsd, 0, sizeof(ddsd));
1515     ddsd.dwSize = sizeof(ddsd);
1516     ddsd.dwFlags = DDSD_CAPS;
1517     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1518     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1519     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1520     /* This old ddraw version happily creates explicit front buffers */
1521     memset(&ddsd, 0, sizeof(ddsd));
1522     ddsd.dwSize = sizeof(ddsd);
1523     ddsd.dwFlags = DDSD_CAPS;
1524     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1525     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1526     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1527     IDirectDrawSurface_Release(surface1);
1528
1529     /* Try a single primary and two offscreen plain surfaces */
1530     memset(&ddsd, 0, sizeof(ddsd));
1531     ddsd.dwSize = sizeof(ddsd);
1532     ddsd.dwFlags = DDSD_CAPS;
1533     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1534     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1535     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1536
1537     memset(&ddsd, 0, sizeof(ddsd));
1538     ddsd.dwSize = sizeof(ddsd);
1539     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1540     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1541     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1542     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1543     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1544     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1545
1546     memset(&ddsd, 0, sizeof(ddsd));
1547     ddsd.dwSize = sizeof(ddsd);
1548     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1549     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1550     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1551     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1552     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
1553     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1554
1555     /* This one has a different size */
1556     memset(&ddsd, 0, sizeof(ddsd));
1557     ddsd.dwSize = sizeof(ddsd);
1558     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1559     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1560     ddsd.dwWidth = 128;
1561     ddsd.dwHeight = 128;
1562     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1563     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1564
1565     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
1566     ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1567        "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1568     if(SUCCEEDED(hr))
1569     {
1570         /* Try the reverse without detaching first */
1571         hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1572         ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
1573         hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1574         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1575     }
1576     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1577     ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1578        "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1579     if(SUCCEEDED(hr))
1580     {
1581         /* Try to detach reversed */
1582         hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1583         ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
1584         /* Now the proper detach */
1585         hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
1586         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1587     }
1588     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3); /* Fails on refrast */
1589     ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1590        "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1591     if(SUCCEEDED(hr))
1592     {
1593         hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
1594         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1595     }
1596     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
1597     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1598     hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
1599     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1600
1601     IDirectDrawSurface_Release(surface4);
1602     IDirectDrawSurface_Release(surface3);
1603     IDirectDrawSurface_Release(surface2);
1604     IDirectDrawSurface_Release(surface1);
1605
1606     hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
1607     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1608
1609     DestroyWindow(window);
1610 }
1611
1612 struct compare
1613 {
1614     DWORD width, height;
1615     DWORD caps, caps2;
1616     UINT mips;
1617 };
1618
1619 static HRESULT WINAPI CubeTestLvl2Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1620 {
1621     UINT *mips = context;
1622
1623     (*mips)++;
1624     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1625                                              context,
1626                                              CubeTestLvl2Enum);
1627
1628     return DDENUMRET_OK;
1629 }
1630
1631 static HRESULT WINAPI CubeTestLvl1Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1632 {
1633     UINT mips = 0;
1634     UINT *num = context;
1635     static const struct compare expected[] =
1636     {
1637         {
1638             128, 128,
1639             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1640             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ,
1641             7
1642         },
1643         {
1644             128, 128,
1645             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1646             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ,
1647             7
1648         },
1649         {
1650             128, 128,
1651             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1652             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY,
1653             7
1654         },
1655         {
1656             128, 128,
1657             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1658             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY,
1659             7
1660         },
1661         {
1662             128, 128,
1663             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1664             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX,
1665             7
1666         },
1667         {
1668             64, 64, /* This is the first mipmap */
1669             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1670             DDSCAPS2_MIPMAPSUBLEVEL | DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX,
1671             6
1672         },
1673     };
1674
1675     mips = 0;
1676     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1677                                              &mips,
1678                                              CubeTestLvl2Enum);
1679
1680     ok(desc->dwWidth == expected[*num].width, "Surface width is %d expected %d\n", desc->dwWidth, expected[*num].width);
1681     ok(desc->dwHeight == expected[*num].height, "Surface height is %d expected %d\n", desc->dwHeight, expected[*num].height);
1682     ok(desc->ddsCaps.dwCaps == expected[*num].caps, "Surface caps are %08x expected %08x\n", desc->ddsCaps.dwCaps, expected[*num].caps);
1683     ok(desc->ddsCaps.dwCaps2 == expected[*num].caps2, "Surface caps2 are %08x expected %08x\n", desc->ddsCaps.dwCaps2, expected[*num].caps2);
1684     ok(mips == expected[*num].mips, "Surface has %d mipmaps, expected %d\n", mips, expected[*num].mips);
1685
1686     (*num)++;
1687
1688     IDirectDrawSurface7_Release(surface);
1689
1690     return DDENUMRET_OK;
1691 }
1692
1693 static void CubeMapTest(void)
1694 {
1695     IDirectDraw7 *dd7 = NULL;
1696     IDirectDrawSurface7 *cubemap = NULL;
1697     DDSURFACEDESC2 ddsd;
1698     HRESULT hr;
1699     UINT num = 0;
1700     struct enumstruct ctx;
1701
1702     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1703     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1704     if (FAILED(hr)) goto err;
1705
1706     memset(&ddsd, 0, sizeof(ddsd));
1707     ddsd.dwSize = sizeof(ddsd);
1708     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1709     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1710     ddsd.dwWidth = 128;
1711     ddsd.dwHeight = 128;
1712     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1713     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1714
1715     /* D3DFMT_R5G6B5 */
1716     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1717     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1718     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1719     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1720     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1721
1722     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1723     if (FAILED(hr))
1724     {
1725         skip("Can't create cubemap surface\n");
1726         goto err;
1727     }
1728
1729     hr = IDirectDrawSurface7_GetSurfaceDesc(cubemap, &ddsd);
1730     ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
1731     ok(ddsd.ddsCaps.dwCaps == (DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX),
1732        "Root Caps are %08x\n", ddsd.ddsCaps.dwCaps);
1733     ok(ddsd.ddsCaps.dwCaps2 == (DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP),
1734        "Root Caps2 are %08x\n", ddsd.ddsCaps.dwCaps2);
1735
1736     IDirectDrawSurface7_EnumAttachedSurfaces(cubemap,
1737                                              &num,
1738                                              CubeTestLvl1Enum);
1739     ok(num == 6, "Surface has %d attachments\n", num);
1740     IDirectDrawSurface7_Release(cubemap);
1741
1742     /* What happens if I do not specify any faces? */
1743     memset(&ddsd, 0, sizeof(ddsd));
1744     ddsd.dwSize = sizeof(ddsd);
1745     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1746     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1747     ddsd.dwWidth = 128;
1748     ddsd.dwHeight = 128;
1749     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1750     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP;
1751
1752     /* D3DFMT_R5G6B5 */
1753     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1754     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1755     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1756     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1757     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1758
1759     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1760     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7::CreateSurface asking for a cube map without faces returned %08x\n", hr);
1761
1762     /* Cube map faces without a cube map? */
1763     memset(&ddsd, 0, sizeof(ddsd));
1764     ddsd.dwSize = sizeof(ddsd);
1765     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1766     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1767     ddsd.dwWidth = 128;
1768     ddsd.dwHeight = 128;
1769     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1770     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_ALLFACES;
1771
1772     /* D3DFMT_R5G6B5 */
1773     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1774     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1775     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1776     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1777     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1778
1779     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1780     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1781
1782     memset(&ddsd, 0, sizeof(ddsd));
1783     ddsd.dwSize = sizeof(ddsd);
1784     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1785     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1786     ddsd.dwWidth = 128;
1787     ddsd.dwHeight = 128;
1788     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1789     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEX;
1790
1791     /* D3DFMT_R5G6B5 */
1792     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1793     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1794     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1795     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1796     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1797
1798     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1799     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1800
1801     /* Make sure everything is cleaned up properly. Use the enumSurfaces test infrastructure */
1802     memset(&ctx, 0, sizeof(ctx));
1803     memset(&ddsd, 0, sizeof(ddsd));
1804     ddsd.dwSize = sizeof(DDSURFACEDESC);
1805     hr = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, (DDSURFACEDESC *) &ddsd, (void *) &ctx, enumCB);
1806     ok(hr == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", hr);
1807     ok(ctx.count == 0, "%d surfaces enumerated, expected 0\n", ctx.count);
1808
1809     err:
1810     if (dd7) IDirectDraw7_Release(dd7);
1811 }
1812
1813 static void test_lockrect_invalid(void)
1814 {
1815     unsigned int i, j;
1816
1817     RECT valid[] = {
1818         {60, 60, 68, 68},
1819         {60, 60, 60, 68},
1820         {60, 60, 68, 60},
1821         {120, 60, 128, 68},
1822         {60, 120, 68, 128},
1823     };
1824
1825     RECT invalid[] = {
1826         {68, 60, 60, 68},       /* left > right */
1827         {60, 68, 68, 60},       /* top > bottom */
1828         {-8, 60,  0, 68},       /* left < surface */
1829         {60, -8, 68,  0},       /* top < surface */
1830         {-16, 60, -8, 68},      /* right < surface */
1831         {60, -16, 68, -8},      /* bottom < surface */
1832         {60, 60, 136, 68},      /* right > surface */
1833         {60, 60, 68, 136},      /* bottom > surface */
1834         {136, 60, 144, 68},     /* left > surface */
1835         {60, 136, 68, 144},     /* top > surface */
1836     };
1837
1838     const DWORD dds_caps[] = {
1839         DDSCAPS_OFFSCREENPLAIN
1840     };
1841
1842     for (j = 0; j < (sizeof(dds_caps) / sizeof(*dds_caps)); ++j)
1843     {
1844         IDirectDrawSurface *surface = 0;
1845         DDSURFACEDESC surface_desc = {0};
1846         DDSURFACEDESC locked_desc = {0};
1847         HRESULT hr;
1848
1849         surface_desc.dwSize = sizeof(surface_desc);
1850         surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
1851         surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1852         surface_desc.ddsCaps.dwCaps = dds_caps[j];
1853         surface_desc.dwWidth = 128;
1854         surface_desc.dwHeight = 128;
1855         surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
1856         U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
1857         U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xFF0000;
1858         U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00FF00;
1859         U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000FF;
1860
1861         hr = IDirectDraw_CreateSurface(lpDD, &surface_desc, &surface, NULL);
1862         ok(SUCCEEDED(hr), "CreateSurface failed (0x%08x)\n", hr);
1863         if (FAILED(hr)) {
1864             skip("failed to create surface\n");
1865             continue;
1866         }
1867
1868         for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i)
1869         {
1870             RECT *rect = &valid[i];
1871
1872             memset(&locked_desc, 0, sizeof(locked_desc));
1873             locked_desc.dwSize = sizeof(locked_desc);
1874
1875             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1876             ok(SUCCEEDED(hr), "Lock failed (0x%08x) for rect [%d, %d]->[%d, %d]\n",
1877                     hr, rect->left, rect->top, rect->right, rect->bottom);
1878
1879             hr = IDirectDrawSurface_Unlock(surface, NULL);
1880             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1881         }
1882
1883         for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i)
1884         {
1885             RECT *rect = &invalid[i];
1886
1887             memset(&locked_desc, 1, sizeof(locked_desc));
1888             locked_desc.dwSize = sizeof(locked_desc);
1889
1890             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1891             ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for rect [%d, %d]->[%d, %d]"
1892                     ", expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, rect->left, rect->top,
1893                     rect->right, rect->bottom, DDERR_INVALIDPARAMS);
1894             ok(!locked_desc.lpSurface, "IDirectDrawSurface_Lock did not set lpSurface in the surface desc to zero.\n");
1895         }
1896
1897         hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1898         ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = NULL) failed (0x%08x)\n", hr);
1899         hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1900         ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned 0x%08x\n", hr);
1901         if(SUCCEEDED(hr)) {
1902             hr = IDirectDrawSurface_Unlock(surface, NULL);
1903             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1904         }
1905         hr = IDirectDrawSurface_Unlock(surface, NULL);
1906         ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1907
1908         memset(&locked_desc, 0, sizeof(locked_desc));
1909         locked_desc.dwSize = sizeof(locked_desc);
1910         hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1911         ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1912            valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1913         hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1914         ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1915            valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1916
1917         /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
1918          * Afterwards unlocking the surface fails(NULL rectangle, and both locked rectangles
1919          */
1920
1921         hr = IDirectDrawSurface_Unlock(surface, NULL);
1922         ok(hr == DD_OK, "Unlock returned (0x%08x)\n", hr);
1923
1924         IDirectDrawSurface_Release(surface);
1925     }
1926 }
1927
1928 static void CompressedTest(void)
1929 {
1930     HRESULT hr;
1931     IDirectDrawSurface7 *surface;
1932     DDSURFACEDESC2 ddsd, ddsd2;
1933     IDirectDraw7 *dd7 = NULL;
1934     RECT r = { 0, 0, 128, 128 };
1935     RECT r2 = { 32, 32, 64, 64 };
1936
1937     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1938     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1939
1940     memset(&ddsd, 0, sizeof(ddsd));
1941     ddsd.dwSize = sizeof(ddsd);
1942     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1943     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1944     ddsd.dwWidth = 128;
1945     ddsd.dwHeight = 128;
1946     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
1947     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
1948     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1949
1950     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1951     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1952     if (FAILED(hr)) {
1953         skip("failed to create surface\n");
1954         return;
1955     }
1956
1957     memset(&ddsd2, 0, sizeof(ddsd2));
1958     ddsd2.dwSize = sizeof(ddsd2);
1959     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1960     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1961     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1962
1963     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1964        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1965     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1966     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1967     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1968        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1969     ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1970     ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1971     IDirectDrawSurface7_Release(surface);
1972
1973     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1974     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1975     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1976     if (FAILED(hr)) {
1977         skip("failed to create surface\n");
1978         return;
1979     }
1980
1981     memset(&ddsd2, 0, sizeof(ddsd2));
1982     ddsd2.dwSize = sizeof(ddsd2);
1983     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1984     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1985     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1986
1987     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1988        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1989     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1990     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1991     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1992        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1993     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1994     IDirectDrawSurface7_Release(surface);
1995
1996     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1997     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1998     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1999     if (FAILED(hr)) {
2000         skip("failed to create surface\n");
2001         return;
2002     }
2003
2004     memset(&ddsd2, 0, sizeof(ddsd2));
2005     ddsd2.dwSize = sizeof(ddsd2);
2006     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2007     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2008     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2009
2010     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2011        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2012     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2013     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2014     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2015        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2016     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2017     ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2018
2019     memset(&ddsd2, 0, sizeof(ddsd2));
2020     ddsd2.dwSize = sizeof(ddsd2);
2021     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2022
2023     /* Show that the description is not changed when locking the surface. What is really interesting
2024      * about this is that DDSD_LPSURFACE isn't set.
2025      */
2026     hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2027     ok(hr == DD_OK, "Lock returned %08x\n", hr);
2028
2029     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2030        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2031     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2032     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2033     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2034        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2035     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2036     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2037
2038     hr = IDirectDrawSurface7_Unlock(surface, NULL);
2039     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2040
2041     /* Now what about a locking rect?  */
2042     hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2043     ok(hr == DD_OK, "Lock returned %08x\n", hr);
2044
2045     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2046        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2047     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2048     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2049     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2050        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2051     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2052     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2053
2054     hr = IDirectDrawSurface7_Unlock(surface, &r);
2055     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2056
2057     /* Now what about a different locking offset? */
2058     hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2059     ok(hr == DD_OK, "Lock returned %08x\n", hr);
2060
2061     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2062        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2063     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2064     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2065     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2066        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2067     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2068     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2069
2070     hr = IDirectDrawSurface7_Unlock(surface, &r2);
2071     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2072     IDirectDrawSurface7_Release(surface);
2073
2074     /* Try this with video memory. A kind of surprise. It still has the LINEARSIZE flag set,
2075      * but seems to have a pitch instead.
2076      */
2077     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
2078     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2079
2080     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2081     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW || hr == DDERR_INVALIDPARAMS ||
2082        broken(hr == DDERR_NODIRECTDRAWHW), "CreateSurface returned %08x\n", hr);
2083
2084     /* Not supported everywhere */
2085     if(SUCCEEDED(hr))
2086     {
2087         memset(&ddsd2, 0, sizeof(ddsd2));
2088         ddsd2.dwSize = sizeof(ddsd2);
2089         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2090         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2091         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2092
2093         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2094         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2095         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2096         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2097         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2098         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2099         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2100         ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2101         IDirectDrawSurface7_Release(surface);
2102
2103         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2104         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2105         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2106
2107         memset(&ddsd2, 0, sizeof(ddsd2));
2108         ddsd2.dwSize = sizeof(ddsd2);
2109         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2110         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2111         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2112
2113         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2114         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2115         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2116         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2117         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2118         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2119         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2120         IDirectDrawSurface7_Release(surface);
2121
2122         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2123         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2124         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2125
2126         memset(&ddsd2, 0, sizeof(ddsd2));
2127         ddsd2.dwSize = sizeof(ddsd2);
2128         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2129         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2130         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2131
2132         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2133         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2134         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2135         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2136         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2137         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2138         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2139         ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2140
2141         memset(&ddsd2, 0, sizeof(ddsd2));
2142         ddsd2.dwSize = sizeof(ddsd2);
2143         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2144
2145         /* Show that the description is not changed when locking the surface. What is really interesting
2146         * about this is that DDSD_LPSURFACE isn't set.
2147         */
2148         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2149         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2150
2151         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2152         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2153         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2154         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2155         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2156         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2157         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2158         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2159
2160         hr = IDirectDrawSurface7_Unlock(surface, NULL);
2161         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2162
2163         /* Now what about a locking rect?  */
2164         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2165         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2166
2167         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2168         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2169         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2170         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2171         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2172         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2173         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2174         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2175
2176         hr = IDirectDrawSurface7_Unlock(surface, &r);
2177         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2178
2179         /* Now what about a different locking offset? */
2180         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2181         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2182
2183         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2184         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2185         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2186         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2187         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2188         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2189         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2190         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2191
2192         hr = IDirectDrawSurface7_Unlock(surface, &r2);
2193         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2194
2195         IDirectDrawSurface7_Release(surface);
2196     }
2197     else
2198     {
2199         skip("Hardware DXTN textures not supported\n");
2200     }
2201
2202     /* What happens to managed textures? Interestingly, Windows reports them as being in system
2203      * memory. The linear size fits again.
2204      */
2205     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2206     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
2207     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2208
2209     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2210     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW, "CreateSurface returned %08x\n", hr);
2211
2212     /* Not supported everywhere */
2213     if(SUCCEEDED(hr))
2214     {
2215         memset(&ddsd2, 0, sizeof(ddsd2));
2216         ddsd2.dwSize = sizeof(ddsd2);
2217         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2218         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2219         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2220
2221         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2222         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2223         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2224         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2225         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2226         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2227         ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2228         ok(ddsd2.ddsCaps.dwCaps2 == DDSCAPS2_TEXTUREMANAGE, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2229         IDirectDrawSurface7_Release(surface);
2230
2231         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2232         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2233         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2234
2235         memset(&ddsd2, 0, sizeof(ddsd2));
2236         ddsd2.dwSize = sizeof(ddsd2);
2237         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2238         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2239         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2240
2241         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2242         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2243         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2244         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2245         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2246         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2247         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2248         IDirectDrawSurface7_Release(surface);
2249
2250         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2251         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2252         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2253
2254         memset(&ddsd2, 0, sizeof(ddsd2));
2255         ddsd2.dwSize = sizeof(ddsd2);
2256         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2257         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2258         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2259
2260         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2261         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2262         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2263         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2264         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2265         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2266         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2267         ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2268
2269         memset(&ddsd2, 0, sizeof(ddsd2));
2270         ddsd2.dwSize = sizeof(ddsd2);
2271         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2272
2273         /* Show that the description is not changed when locking the surface. What is really interesting
2274         * about this is that DDSD_LPSURFACE isn't set.
2275         */
2276         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2277         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2278
2279         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2280         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2281         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2282         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2283         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2284         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2285         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2286         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2287
2288         hr = IDirectDrawSurface7_Unlock(surface, NULL);
2289         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2290
2291         /* Now what about a locking rect?  */
2292         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2293         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2294
2295         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2296         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2297         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2298         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2299         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2300         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2301         ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2302         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2303
2304         hr = IDirectDrawSurface7_Unlock(surface, &r);
2305         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2306
2307         /* Now what about a different locking offset? */
2308         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2309         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2310
2311         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2312         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2313         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2314         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2315         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2316         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2317         ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2318         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2319
2320         hr = IDirectDrawSurface7_Unlock(surface, &r2);
2321         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2322
2323         IDirectDrawSurface7_Release(surface);
2324     }
2325     else
2326     {
2327         skip("Hardware DXTN textures not supported\n");
2328     }
2329
2330     IDirectDraw7_Release(dd7);
2331 }
2332
2333 static void SizeTest(void)
2334 {
2335     LPDIRECTDRAWSURFACE dsurface = NULL;
2336     DDSURFACEDESC desc;
2337     HRESULT ret;
2338     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2339
2340     /* Create an offscreen surface surface without a size */
2341     ZeroMemory(&desc, sizeof(desc));
2342     desc.dwSize = sizeof(desc);
2343     desc.dwFlags = DDSD_CAPS;
2344     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2345     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2346     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without a size info returned %08x (dsurface=%p)\n", ret, dsurface);
2347     if(dsurface)
2348     {
2349         trace("Surface at %p\n", dsurface);
2350         IDirectDrawSurface_Release(dsurface);
2351         dsurface = NULL;
2352     }
2353
2354     /* Create an offscreen surface surface with only a width parameter */
2355     ZeroMemory(&desc, sizeof(desc));
2356     desc.dwSize = sizeof(desc);
2357     desc.dwFlags = DDSD_CAPS | DDSD_WIDTH;
2358     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2359     desc.dwWidth = 128;
2360     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2361     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without hight info returned %08x\n", ret);
2362     if(dsurface)
2363     {
2364         IDirectDrawSurface_Release(dsurface);
2365         dsurface = NULL;
2366     }
2367
2368     /* Create an offscreen surface surface with only a height parameter */
2369     ZeroMemory(&desc, sizeof(desc));
2370     desc.dwSize = sizeof(desc);
2371     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT;
2372     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2373     desc.dwHeight = 128;
2374     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2375     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without width info returned %08x\n", ret);
2376     if(dsurface)
2377     {
2378         IDirectDrawSurface_Release(dsurface);
2379         dsurface = NULL;
2380     }
2381
2382     /* Sanity check */
2383     ZeroMemory(&desc, sizeof(desc));
2384     desc.dwSize = sizeof(desc);
2385     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2386     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2387     desc.dwHeight = 128;
2388     desc.dwWidth = 128;
2389     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2390     ok(ret == DD_OK, "Creating an offscreen plain surface with width and height info returned %08x\n", ret);
2391     if(dsurface)
2392     {
2393         IDirectDrawSurface_Release(dsurface);
2394         dsurface = NULL;
2395     }
2396
2397     /* Test a primary surface size */
2398     ret = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_NORMAL);
2399     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2400
2401     ZeroMemory(&desc, sizeof(desc));
2402     desc.dwSize = sizeof(desc);
2403     desc.dwFlags = DDSD_CAPS;
2404     desc.ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
2405     desc.dwHeight = 128; /* Keep them set to  check what happens */
2406     desc.dwWidth = 128; /* Keep them set to  check what happens */
2407     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2408     ok(ret == DD_OK, "Creating a primary surface without width and height info returned %08x\n", ret);
2409     if(dsurface)
2410     {
2411         ret = IDirectDrawSurface_GetSurfaceDesc(dsurface, &desc);
2412         ok(ret == DD_OK, "GetSurfaceDesc returned %x\n", ret);
2413
2414         IDirectDrawSurface_Release(dsurface);
2415         dsurface = NULL;
2416
2417         ok(desc.dwFlags & DDSD_WIDTH, "Primary surface doesn't have width set\n");
2418         ok(desc.dwFlags & DDSD_HEIGHT, "Primary surface doesn't have height set\n");
2419         ok(desc.dwWidth == GetSystemMetrics(SM_CXSCREEN), "Surface width differs from screen width\n");
2420         ok(desc.dwHeight == GetSystemMetrics(SM_CYSCREEN), "Surface height differs from screen height\n");
2421     }
2422     ret = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
2423     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2424 }
2425
2426 static void PrivateDataTest(void)
2427 {
2428     HRESULT hr;
2429     IDirectDrawSurface7 *surface7 = NULL;
2430     IDirectDrawSurface *surface = NULL;
2431     DDSURFACEDESC desc;
2432     ULONG ref, ref2;
2433     IUnknown *ptr;
2434     DWORD size = sizeof(IUnknown *);
2435
2436     ZeroMemory(&desc, sizeof(desc));
2437     desc.dwSize = sizeof(desc);
2438     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2439     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2440     desc.dwHeight = 128;
2441     desc.dwWidth = 128;
2442     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface, NULL);
2443     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2444     if(!surface)
2445     {
2446         return;
2447     }
2448     hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **) &surface7);
2449     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2450     if(!surface7)
2451     {
2452         IDirectDrawSurface_Release(surface);
2453         return;
2454     }
2455
2456     /* This fails */
2457     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 0, DDSPD_IUNKNOWNPOINTER);
2458     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2459     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 5, DDSPD_IUNKNOWNPOINTER);
2460     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2461     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *) * 2, DDSPD_IUNKNOWNPOINTER);
2462     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2463
2464     ref = getref((IUnknown *) lpDD);
2465     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2466     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2467     ref2 = getref((IUnknown *) lpDD);
2468     ok(ref2 == ref + 1, "Object reference is %d, expected %d\n", ref2, ref + 1);
2469     hr = IDirectDrawSurface7_FreePrivateData(surface7, &IID_IDirectDrawSurface7);
2470     ok(SUCCEEDED(hr), "IDirectDrawSurface7_FreePrivateData returned %#x.\n", hr);
2471     ref2 = getref((IUnknown *) lpDD);
2472     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2473
2474     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2475     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2476     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, surface7, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2477     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2478     ref2 = getref((IUnknown *) lpDD);
2479     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2480
2481     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2482     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2483     hr = IDirectDrawSurface7_GetPrivateData(surface7, &IID_IDirectDrawSurface7, &ptr, &size);
2484     ok(hr == DD_OK, "IDirectDrawSurface7_GetPrivateData failed with %08x\n", hr);
2485     ref2 = getref((IUnknown *) lpDD);
2486     /* Object is NOT being addrefed */
2487     ok(ptr == (IUnknown *) lpDD, "Returned interface pointer is %p, expected %p\n", ptr, lpDD);
2488     ok(ref2 == ref + 1, "Object reference is %d, expected %d. ptr at %p, orig at %p\n", ref2, ref + 1, ptr, lpDD);
2489
2490     IDirectDrawSurface_Release(surface);
2491     IDirectDrawSurface7_Release(surface7);
2492
2493     /* Destroying the surface frees the held reference */
2494     ref2 = getref((IUnknown *) lpDD);
2495     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2496 }
2497
2498 static void BltParamTest(void)
2499 {
2500     IDirectDrawSurface *surface1 = NULL, *surface2 = NULL;
2501     DDSURFACEDESC desc;
2502     HRESULT hr;
2503     DDBLTFX BltFx;
2504     RECT valid = {10, 10, 20, 20};
2505     RECT invalid1 = {20, 10, 10, 20};
2506     RECT invalid2 = {20, 20, 20, 20};
2507     RECT invalid3 = {-1, -1, 20, 20};
2508     RECT invalid4 = {60, 60, 70, 70};
2509
2510     memset(&desc, 0, sizeof(desc));
2511     desc.dwSize = sizeof(desc);
2512     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2513     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2514     desc.dwHeight = 128;
2515     desc.dwWidth = 128;
2516     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface1, NULL);
2517     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2518
2519     desc.dwHeight = 64;
2520     desc.dwWidth = 64;
2521     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface2, NULL);
2522     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2523
2524     if(0)
2525     {
2526         /* This crashes */
2527         hr = IDirectDrawSurface_BltFast(surface1, 0, 0, NULL, NULL, 0);
2528         ok(hr == DD_OK, "BltFast from NULL surface returned %08x\n", hr);
2529     }
2530     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, NULL, 0);
2531     ok(hr == DD_OK, "BltFast from smaller to bigger surface returned %08x\n", hr);
2532     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, NULL, 0);
2533     ok(hr == DDERR_INVALIDRECT, "BltFast from bigger to smaller surface returned %08x\n", hr);
2534     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &valid, 0);
2535     ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle returned %08x\n", hr);
2536     hr = IDirectDrawSurface_BltFast(surface2, 60, 60, surface1, &valid, 0);
2537     ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2538     hr = IDirectDrawSurface_BltFast(surface1, 90, 90, surface2, NULL, 0);
2539     ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2540     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid1, 0);
2541     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 1 returned %08x\n", hr);
2542     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid2, 0);
2543     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 2 returned %08x\n", hr);
2544     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid3, 0);
2545     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2546     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, &invalid4, 0);
2547     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2548     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface1, NULL, 0);
2549     ok(hr == DD_OK, "BltFast blitting a surface onto itself returned %08x\n", hr);
2550
2551     /* Blt(non-fast) tests */
2552     memset(&BltFx, 0, sizeof(BltFx));
2553     BltFx.dwSize = sizeof(BltFx);
2554     U5(BltFx).dwFillColor = 0xaabbccdd;
2555
2556     hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2557     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a valid rectangle for color fill returned %08x\n", hr);
2558     hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, &invalid3, DDBLT_COLORFILL, &BltFx);
2559     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a invalid, unused rectangle returned %08x\n", hr);
2560     hr = IDirectDrawSurface_Blt(surface2, &invalid1, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2561     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2562     hr = IDirectDrawSurface_Blt(surface2, &invalid2, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2563     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2564     hr = IDirectDrawSurface_Blt(surface2, &invalid3, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2565     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2566     hr = IDirectDrawSurface_Blt(surface2, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2567     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2568
2569     /* Valid on surface 1 */
2570     hr = IDirectDrawSurface_Blt(surface1, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2571     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a subrectangle fill returned %08x\n", hr);
2572
2573     /* Works - stretched blit */
2574     hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, NULL, 0, NULL);
2575     ok(hr == DD_OK, "IDirectDrawSurface_Blt from a smaller to a bigger surface returned %08x\n", hr);
2576     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, NULL, 0, NULL);
2577     ok(hr == DD_OK, "IDirectDrawSurface_Blt from a bigger to a smaller surface %08x\n", hr);
2578
2579     /* Invalid dest rects in sourced blits */
2580     hr = IDirectDrawSurface_Blt(surface2, &invalid1, surface1, NULL, 0, NULL);
2581     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2582     hr = IDirectDrawSurface_Blt(surface2, &invalid2, surface1, NULL, 0, NULL);
2583     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2584     hr = IDirectDrawSurface_Blt(surface2, &invalid3, surface1, NULL, 0, NULL);
2585     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2586     hr = IDirectDrawSurface_Blt(surface2, &invalid4, surface1, NULL, 0, NULL);
2587     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2588
2589     /* Invalid src rects */
2590     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid1, 0, NULL);
2591     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2592     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid2, 0, NULL);
2593     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2594     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid3, 0, NULL);
2595     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2596     hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, &invalid4, 0, NULL);
2597     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2598
2599     IDirectDrawSurface_Release(surface1);
2600     IDirectDrawSurface_Release(surface2);
2601 }
2602
2603 static void PaletteTest(void)
2604 {
2605     HRESULT hr;
2606     LPDIRECTDRAWSURFACE lpSurf = NULL;
2607     DDSURFACEDESC ddsd;
2608     IDirectDrawPalette *palette = NULL;
2609     PALETTEENTRY Table[256];
2610     PALETTEENTRY palEntries[256];
2611     int i;
2612
2613     for(i=0; i<256; i++)
2614     {
2615         Table[i].peRed   = 0xff;
2616         Table[i].peGreen = 0;
2617         Table[i].peBlue  = 0;
2618         Table[i].peFlags = 0;
2619     }
2620
2621     /* Create a 8bit palette without DDPCAPS_ALLOW256 set */
2622     hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_8BIT, Table, &palette, NULL);
2623     ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2624     if (FAILED(hr)) goto err;
2625     /* Read back the palette and verify the entries. Without DDPCAPS_ALLOW256 set
2626     /  entry 0 and 255 should have been overwritten with black and white */
2627     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2628     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2629     if(hr == DD_OK)
2630     {
2631         ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2632            "Palette entry 0 of a palette without DDPCAPS_ALLOW256 set should be (0,0,0) but it is (%d,%d,%d)\n",
2633            palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2634         ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2635            "Palette entry 255 of a palette without DDPCAPS_ALLOW256 set should be (255,255,255) but it is (%d,%d,%d)\n",
2636            palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2637
2638         /* Entry 1-254 should contain red */
2639         for(i=1; i<255; i++)
2640             ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2641                "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2642                i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2643     }
2644
2645     /* CreatePalette without DDPCAPS_ALLOW256 ignores entry 0 and 255,
2646     /  now check we are able to update the entries afterwards. */
2647     IDirectDrawPalette_SetEntries(palette , 0, 0, 256, &Table[0]);
2648     ok(hr == DD_OK, "SetEntries failed with %08x\n", hr);
2649     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2650     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2651     if(hr == DD_OK)
2652     {
2653         ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2654            "Palette entry 0 should have been set to (0,0,0) but it contains (%d,%d,%d)\n",
2655            palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2656         ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2657            "Palette entry 255 should have been set to (255,255,255) but it contains (%d,%d,%d)\n",
2658            palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2659     }
2660     IDirectDrawPalette_Release(palette);
2661
2662     /* Create a 8bit palette with DDPCAPS_ALLOW256 set */
2663     hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
2664     ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2665     if (FAILED(hr)) goto err;
2666
2667     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2668     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2669     if(hr == DD_OK)
2670     {
2671         /* All entries should contain red */
2672         for(i=0; i<256; i++)
2673             ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2674                "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2675                i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2676     }
2677
2678     /* Try to set palette to a non-palettized surface */
2679     ddsd.dwSize = sizeof(ddsd);
2680     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2681     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2682     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2683     ddsd.dwWidth = 800;
2684     ddsd.dwHeight = 600;
2685     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2686     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
2687     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
2688     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
2689     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
2690     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurf, NULL);
2691     ok(hr==DD_OK, "CreateSurface returned: %x\n",hr);
2692     if (FAILED(hr)) {
2693         skip("failed to create surface\n");
2694         goto err;
2695     }
2696
2697     hr = IDirectDrawSurface_SetPalette(lpSurf, palette);
2698     ok(hr == DDERR_INVALIDPIXELFORMAT, "CreateSurface returned: %x\n",hr);
2699
2700     IDirectDrawPalette_Release(palette);
2701     palette = NULL;
2702
2703     hr = IDirectDrawSurface_GetPalette(lpSurf, &palette);
2704     ok(hr == DDERR_NOPALETTEATTACHED, "CreateSurface returned: %x\n",hr);
2705
2706     err:
2707
2708     if (lpSurf) IDirectDrawSurface_Release(lpSurf);
2709     if (palette) IDirectDrawPalette_Release(palette);
2710 }
2711
2712 static void StructSizeTest(void)
2713 {
2714     IDirectDrawSurface *surface1;
2715     IDirectDrawSurface7 *surface7;
2716     union {
2717         DDSURFACEDESC desc1;
2718         DDSURFACEDESC2 desc2;
2719         char blob[1024]; /* To get a bunch of writable memory */
2720     } desc;
2721     DDSURFACEDESC create;
2722     HRESULT hr;
2723
2724     memset(&desc, 0, sizeof(desc));
2725     memset(&create, 0, sizeof(create));
2726
2727     memset(&create, 0, sizeof(create));
2728     create.dwSize = sizeof(create);
2729     create.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2730     create.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2731     create.dwHeight = 128;
2732     create.dwWidth = 128;
2733     hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2734     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2735     hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface7, (void **) &surface7);
2736     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2737
2738     desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2739     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2740     ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2741     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2742     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2743
2744     desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2745     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2746     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2747     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2748     ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2749
2750     desc.desc2.dwSize = 0;
2751     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2752     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2753     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2754     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2755
2756     desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2757     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2758     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2759     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2760     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2761
2762     desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2763     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2764     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2765     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2766     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2767
2768     /* Tests for Lock() */
2769
2770     desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2771     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2772     ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2773     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2774     ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2775     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2776     ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2777     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2778     ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2779
2780     desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2781     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2782     ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2783     ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2784     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2785     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2786     ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2787     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2788     ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2789
2790     desc.desc2.dwSize = 0;
2791     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2792     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size 0 returned %08x\n", hr);
2793     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2794     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2795     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size 0 returned %08x\n", hr);
2796     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2797
2798     desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2799     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2800     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2801     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2802     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2803     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2804     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2805
2806     desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2807     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2808     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2809     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2810     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2811     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2812     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2813
2814     IDirectDrawSurface7_Release(surface7);
2815     IDirectDrawSurface_Release(surface1);
2816 }
2817
2818 static void SurfaceCapsTest(void)
2819 {
2820     DDSURFACEDESC create;
2821     DDSURFACEDESC desc;
2822     HRESULT hr;
2823     IDirectDrawSurface *surface1 = NULL;
2824     DDSURFACEDESC2 create2, desc2;
2825     IDirectDrawSurface7 *surface7 = NULL;
2826     IDirectDraw7 *dd7 = NULL;
2827     DWORD create_caps[] = {
2828         DDSCAPS_OFFSCREENPLAIN,
2829         DDSCAPS_TEXTURE,
2830         DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD,
2831         0,
2832         DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2833         DDSCAPS_PRIMARYSURFACE,
2834         DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY
2835     };
2836     DWORD expected_caps[] = {
2837         DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2838         DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2839         DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD,
2840         DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2841         DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2842         DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_VISIBLE,
2843         DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_VISIBLE
2844     };
2845     UINT i;
2846     DDCAPS ddcaps;
2847
2848     /* Tests various surface flags, what changes do they undergo during surface creation. Forsaken
2849      * engine expects texture surfaces without memory flag to get a video memory flag right after
2850      * creation. Currently, Wine adds DDSCAPS_FRONTBUFFER to primary surface, but native doesn't do this
2851      * for single buffered primaries. Because of this primary surface creation tests are todo_wine. No real
2852      * app is known so far to care about this. */
2853     ddcaps.dwSize = sizeof(DDCAPS);
2854     hr = IDirectDraw_GetCaps(lpDD, &ddcaps, NULL);
2855     ok(hr == DD_OK, "IDirectDraw_GetCaps failed with %08x\n", hr);
2856
2857     if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
2858     {
2859         skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
2860         return ;
2861     }
2862
2863     for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2864     {
2865         memset(&create, 0, sizeof(create));
2866         create.dwSize = sizeof(create);
2867         create.ddsCaps.dwCaps = create_caps[i];
2868         create.dwFlags = DDSD_CAPS;
2869
2870         if (!(create.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2871         {
2872             create.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2873             create.dwHeight = 128;
2874             create.dwWidth = 128;
2875         }
2876
2877         hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2878         ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2879
2880         if (SUCCEEDED(hr))
2881         {
2882             memset(&desc, 0, sizeof(desc));
2883             desc.dwSize = sizeof(DDSURFACEDESC);
2884             hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc);
2885             ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2886
2887             if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
2888                 ok(desc.ddsCaps.dwCaps == expected_caps[i],
2889                     "GetSurfaceDesc returned caps %x, expected %x\n", desc.ddsCaps.dwCaps,
2890                     expected_caps[i]);
2891             else
2892                 todo_wine ok(desc.ddsCaps.dwCaps == expected_caps[i],
2893                                 "GetSurfaceDesc returned caps %x, expected %x\n", desc.ddsCaps.dwCaps,
2894                                 expected_caps[i]);
2895
2896             IDirectDrawSurface_Release(surface1);
2897         }
2898     }
2899
2900     /* Test for differences in ddraw 7 */
2901     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2902     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
2903     if (FAILED(hr))
2904     {
2905         skip("Failed to get IDirectDraw7 interface, skipping tests\n");
2906     }
2907     else
2908     {
2909         for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2910         {
2911             memset(&create2, 0, sizeof(create2));
2912             create2.dwSize = sizeof(create2);
2913             create2.ddsCaps.dwCaps = create_caps[i];
2914             create2.dwFlags = DDSD_CAPS;
2915
2916             if (!(create2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2917             {
2918                 create2.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2919                 create2.dwHeight = 128;
2920                 create2.dwWidth = 128;
2921             }
2922
2923             hr = IDirectDraw7_CreateSurface(dd7, &create2, &surface7, NULL);
2924             ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2925
2926             if (SUCCEEDED(hr))
2927             {
2928                 memset(&desc2, 0, sizeof(desc2));
2929                 desc2.dwSize = sizeof(DDSURFACEDESC2);
2930                 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc2);
2931                 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2932
2933                 if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
2934                     ok(desc2.ddsCaps.dwCaps == expected_caps[i],
2935                         "GetSurfaceDesc returned caps %x, expected %x\n", desc2.ddsCaps.dwCaps,
2936                         expected_caps[i]);
2937                 else
2938                     todo_wine ok(desc2.ddsCaps.dwCaps == expected_caps[i],
2939                                     "GetSurfaceDesc returned caps %x, expected %x\n", desc2.ddsCaps.dwCaps,
2940                                     expected_caps[i]);
2941
2942                 IDirectDrawSurface7_Release(surface7);
2943             }
2944         }
2945
2946         IDirectDraw7_Release(dd7);
2947     }
2948
2949     memset(&create, 0, sizeof(create));
2950     create.dwSize = sizeof(create);
2951     create.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2952     create.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY;
2953     create.dwWidth = 64;
2954     create.dwHeight = 64;
2955     hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2956     ok(hr == DDERR_INVALIDCAPS, "Creating a SYSMEM | VIDMEM surface returned 0x%08x, expected DDERR_INVALIDCAPS\n", hr);
2957     if(surface1) IDirectDrawSurface_Release(surface1);
2958 }
2959
2960 static BOOL can_create_primary_surface(void)
2961 {
2962     DDSURFACEDESC ddsd;
2963     IDirectDrawSurface *surface;
2964     HRESULT hr;
2965
2966     memset(&ddsd, 0, sizeof(ddsd));
2967     ddsd.dwSize = sizeof(ddsd);
2968     ddsd.dwFlags = DDSD_CAPS;
2969     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2970     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2971     if(FAILED(hr)) return FALSE;
2972     IDirectDrawSurface_Release(surface);
2973     return TRUE;
2974 }
2975
2976 static void dctest_surf(IDirectDrawSurface *surf, int ddsdver) {
2977     HRESULT hr;
2978     HDC dc, dc2 = (HDC) 0x1234;
2979     DDSURFACEDESC ddsd;
2980     DDSURFACEDESC2 ddsd2;
2981
2982     memset(&ddsd, 0, sizeof(ddsd));
2983     ddsd.dwSize = sizeof(ddsd);
2984     memset(&ddsd2, 0, sizeof(ddsd2));
2985     ddsd2.dwSize = sizeof(ddsd2);
2986
2987     hr = IDirectDrawSurface_GetDC(surf, &dc);
2988     ok(hr == DD_OK, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
2989
2990     hr = IDirectDrawSurface_GetDC(surf, &dc2);
2991     ok(hr == DDERR_DCALREADYCREATED, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
2992     ok(dc2 == (HDC) 0x1234, "The failed GetDC call changed the dc: %p\n", dc2);
2993
2994     hr = IDirectDrawSurface_Lock(surf, NULL, ddsdver == 1 ? &ddsd : ((DDSURFACEDESC *) &ddsd2), 0, NULL);
2995     ok(hr == DDERR_SURFACEBUSY, "IDirectDrawSurface_Lock returned 0x%08x, expected DDERR_ALREADYLOCKED\n", hr);
2996
2997     hr = IDirectDrawSurface_ReleaseDC(surf, dc);
2998     ok(hr == DD_OK, "IDirectDrawSurface_ReleaseDC failed: 0x%08x\n", hr);
2999     hr = IDirectDrawSurface_ReleaseDC(surf, dc);
3000     ok(hr == DDERR_NODC, "IDirectDrawSurface_ReleaseDC returned 0x%08x, expected DDERR_NODC\n", hr);
3001 }
3002
3003 static void GetDCTest(void)
3004 {
3005     DDSURFACEDESC ddsd;
3006     DDSURFACEDESC2 ddsd2;
3007     IDirectDrawSurface *surf;
3008     IDirectDrawSurface2 *surf2;
3009     IDirectDrawSurface4 *surf4;
3010     IDirectDrawSurface7 *surf7;
3011     HRESULT hr;
3012     IDirectDraw2 *dd2;
3013     IDirectDraw4 *dd4;
3014     IDirectDraw7 *dd7;
3015
3016     memset(&ddsd, 0, sizeof(ddsd));
3017     ddsd.dwSize = sizeof(ddsd);
3018     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3019     ddsd.dwWidth = 64;
3020     ddsd.dwHeight = 64;
3021     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3022     memset(&ddsd2, 0, sizeof(ddsd2));
3023     ddsd2.dwSize = sizeof(ddsd2);
3024     ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3025     ddsd2.dwWidth = 64;
3026     ddsd2.dwHeight = 64;
3027     ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3028
3029     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
3030     ok(hr == DD_OK, "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3031     dctest_surf(surf, 1);
3032     IDirectDrawSurface_Release(surf);
3033
3034     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3035     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3036
3037     hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3038     ok(hr == DD_OK, "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
3039     dctest_surf(surf, 1);
3040
3041     hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
3042     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr);
3043     dctest_surf((IDirectDrawSurface *) surf2, 1);
3044
3045     IDirectDrawSurface2_Release(surf2);
3046     IDirectDrawSurface_Release(surf);
3047     IDirectDraw2_Release(dd2);
3048
3049     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3050     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3051
3052     surf = NULL;
3053     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3054     ok(hr == DD_OK, "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
3055     dctest_surf((IDirectDrawSurface *) surf4, 2);
3056
3057     IDirectDrawSurface4_Release(surf4);
3058     IDirectDraw4_Release(dd4);
3059
3060     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3061     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3062     surf = NULL;
3063     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3064     ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
3065     dctest_surf((IDirectDrawSurface *) surf7, 2);
3066
3067     IDirectDrawSurface7_Release(surf7);
3068     IDirectDraw7_Release(dd7);
3069 }
3070
3071 static void GetDCFormatTest(void)
3072 {
3073     DDSURFACEDESC2 ddsd;
3074     unsigned int i;
3075     IDirectDrawSurface7 *surface;
3076     IDirectDraw7 *dd7;
3077     HRESULT hr;
3078     HDC dc;
3079
3080     struct
3081     {
3082         const char *name;
3083         DDPIXELFORMAT fmt;
3084         BOOL getdc_capable;
3085         HRESULT alt_result;
3086     } testdata[] = {
3087         {
3088             "D3DFMT_A8R8G8B8",
3089             {
3090                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3091                 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
3092             },
3093             TRUE
3094         },
3095         {
3096             "D3DFMT_X8R8G8B8",
3097             {
3098                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3099                 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
3100             },
3101             TRUE
3102         },
3103         {
3104             "D3DFMT_X8B8G8R8",
3105             {
3106                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3107                 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
3108             },
3109             TRUE,
3110             DDERR_CANTCREATEDC /* Vista+ */
3111         },
3112         {
3113             "D3DFMT_X8B8G8R8",
3114             {
3115                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3116                        {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}
3117             },
3118             TRUE,
3119             DDERR_CANTCREATEDC /* Vista+ */
3120         },
3121         {
3122             "D3DFMT_A4R4G4B4",
3123             {
3124                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3125                        {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}
3126             },
3127             TRUE,
3128             DDERR_CANTCREATEDC /* Vista+ */
3129         },
3130         {
3131             "D3DFMT_X4R4G4B4",
3132             {
3133                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3134                        {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}
3135             },
3136             TRUE,
3137             DDERR_CANTCREATEDC /* Vista+ */
3138         },
3139         {
3140             "D3DFMT_R5G6B5",
3141             {
3142                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3143                        {16}, {0x0000F800}, {0x000007E0}, {0x0000001F}, {0x00000000}
3144             },
3145             TRUE
3146         },
3147         {
3148             "D3DFMT_A1R5G5B5",
3149             {
3150                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3151                        {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00008000}
3152             },
3153             TRUE
3154         },
3155         {
3156             "D3DFMT_X1R5G5B5",
3157             {
3158                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3159                        {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00000000}
3160             },
3161             TRUE
3162         },
3163         {
3164             "D3DFMT_R3G3B2",
3165             {
3166                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3167                        { 8}, {0x000000E0}, {0x0000001C}, {0x00000003}, {0x00000000}
3168             },
3169             FALSE
3170         },
3171         {
3172             /* Untested, windows test machine didn't support this format */
3173             "D3DFMT_A2R10G10B10",
3174             {
3175                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3176                        {32}, {0xC0000000}, {0x3FF00000}, {0x000FFC00}, {0x000003FF}
3177             },
3178             TRUE
3179         },
3180         /*
3181          * GetDC on a P8 surface fails unless the display mode is 8 bpp. This is not
3182          * implemented in wine yet, so disable the test for now. Succeeding P8 getDC
3183          * calls are tested in the ddraw.visual test.
3184          *
3185         {
3186             "D3DFMT_P8",
3187             {
3188                 sizeof(DDPIXELFORMAT), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0,
3189                 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3190             },
3191             FALSE
3192         },
3193          */
3194         {
3195             "D3DFMT_L8",
3196             {
3197                 sizeof(DDPIXELFORMAT), DDPF_LUMINANCE, 0,
3198                 {8 }, {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}
3199             },
3200             FALSE
3201         },
3202         {
3203             "D3DFMT_A8L8",
3204             {
3205                 sizeof(DDPIXELFORMAT), DDPF_ALPHAPIXELS | DDPF_LUMINANCE, 0,
3206                 {16}, {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}
3207             },
3208             FALSE
3209         },
3210         {
3211             "D3DFMT_DXT1",
3212             {
3213                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','1'),
3214                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3215             },
3216             FALSE
3217         },
3218         {
3219             "D3DFMT_DXT2",
3220             {
3221                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','2'),
3222                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3223             },
3224             FALSE
3225         },
3226         {
3227             "D3DFMT_DXT3",
3228             {
3229                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','3'),
3230                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3231             },
3232             FALSE
3233         },
3234         {
3235             "D3DFMT_DXT4",
3236             {
3237                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','4'),
3238                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3239             },
3240             FALSE
3241         },
3242         {
3243             "D3DFMT_DXT5",
3244             {
3245                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','5'),
3246                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3247             },
3248             FALSE
3249         },
3250     };
3251
3252     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3253     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed, hr = 0x%08x\n", hr);
3254
3255     for(i = 0; i < (sizeof(testdata) / sizeof(testdata[0])); i++)
3256     {
3257         memset(&ddsd, 0, sizeof(ddsd));
3258         ddsd.dwSize = sizeof(ddsd);
3259         ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3260         ddsd.dwWidth = 64;
3261         ddsd.dwHeight = 64;
3262         U4(ddsd).ddpfPixelFormat = testdata[i].fmt;
3263         ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3264
3265         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3266         if(FAILED(hr))
3267         {
3268             ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
3269             ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
3270             hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3271             if(FAILED(hr))
3272             {
3273                 skip("IDirectDraw7_CreateSurface failed, hr = 0x%08x, format %s\n", hr, testdata[i].name);
3274                 continue;
3275             }
3276         }
3277
3278         dc = (void *) 0x1234;
3279         hr = IDirectDrawSurface7_GetDC(surface, &dc);
3280         if(testdata[i].getdc_capable)
3281         {
3282             ok(SUCCEEDED(hr) ||
3283                (testdata[i].alt_result && hr == testdata[i].alt_result),
3284                "GetDC on a %s surface failed(0x%08x), expected it to work\n",
3285                testdata[i].name, hr);
3286         }
3287         else
3288         {
3289             ok(FAILED(hr), "GetDC on a %s surface succeeded(0x%08x), expected it to fail\n",
3290                testdata[i].name, hr);
3291         }
3292
3293         if(SUCCEEDED(hr))
3294         {
3295             IDirectDrawSurface7_ReleaseDC(surface, dc);
3296             ok(hr == DD_OK, "IDirectDrawSurface7_ReleaseDC failed, hr = 0x%08x\n", hr);
3297             dc = 0;
3298         }
3299         else
3300         {
3301             ok(dc == NULL, "After failed GetDC dc is %p\n", dc);
3302         }
3303
3304         IDirectDrawSurface7_Release(surface);
3305     }
3306
3307     IDirectDraw7_Release(dd7);
3308 }
3309
3310 START_TEST(dsurface)
3311 {
3312     HRESULT ret;
3313     IDirectDraw4 *dd4;
3314
3315     if (!CreateDirectDraw())
3316         return;
3317
3318     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3319     if (ret == E_NOINTERFACE)
3320     {
3321         win_skip("DirectDraw4 and higher are not supported\n");
3322         ReleaseDirectDraw();
3323         return;
3324     }
3325     IDirectDraw_Release(dd4);
3326
3327     if(!can_create_primary_surface())
3328     {
3329         skip("Unable to create primary surface\n");
3330         return;
3331     }
3332
3333     MipMapCreationTest();
3334     SrcColorKey32BlitTest();
3335     QueryInterface();
3336     GetDDInterface_1();
3337     GetDDInterface_2();
3338     GetDDInterface_4();
3339     GetDDInterface_7();
3340     IFaceRefCount();
3341     EnumTest();
3342     AttachmentTest();
3343     AttachmentTest7();
3344     CubeMapTest();
3345     test_lockrect_invalid();
3346     CompressedTest();
3347     SizeTest();
3348     PrivateDataTest();
3349     BltParamTest();
3350     StructSizeTest();
3351     PaletteTest();
3352     SurfaceCapsTest();
3353     GetDCTest();
3354     GetDCFormatTest();
3355     ReleaseDirectDraw();
3356 }