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