dinput: Fix printing NULL strings.
[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     ctx.count = 0;
1221     rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, NULL, &ctx, enumCB);
1222     ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
1223     ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
1224
1225     IDirectDrawSurface_Release(ctx.expected[2]);
1226     IDirectDrawSurface_Release(ctx.expected[1]);
1227     IDirectDrawSurface_Release(surface);
1228 }
1229
1230 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1231 {
1232     UINT *num = context;
1233     (*num)++;
1234     IDirectDrawSurface_Release(surface);
1235     return DDENUMRET_OK;
1236 }
1237
1238 static void AttachmentTest7(void)
1239 {
1240     HRESULT hr;
1241     IDirectDraw7 *dd7;
1242     IDirectDrawSurface7 *surface1, *surface2, *surface3, *surface4;
1243     DDSURFACEDESC2 ddsd, ddsd2;
1244     UINT num;
1245     DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0}, caps2 = {DDSCAPS_BACKBUFFER,0,0,0};
1246     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1247
1248     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1249     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1250
1251     memset(&ddsd, 0, sizeof(ddsd));
1252     ddsd.dwSize = sizeof(ddsd);
1253     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1254     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1255     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1256     ddsd.dwWidth = 128;
1257     ddsd.dwHeight = 128;
1258     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1259     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1260
1261     /* ROOT */
1262     num = 0;
1263     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1264     ok(num == 1, "Mipmap root has %d surfaces attached, expected 1\n", num);
1265     /* DONE ROOT */
1266
1267     /* LEVEL 1 */
1268     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1269     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1270     num = 0;
1271     IDirectDrawSurface7_EnumAttachedSurfaces(surface2, &num, SurfaceCounter);
1272     ok(num == 1, "First mip level has %d surfaces attached, expected 1\n", num);
1273     /* DONE LEVEL 1 */
1274
1275     /* LEVEL 2 */
1276     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1277     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1278     IDirectDrawSurface7_Release(surface2);
1279     num = 0;
1280     IDirectDrawSurface7_EnumAttachedSurfaces(surface3, &num, SurfaceCounter);
1281     ok(num == 0, "Second mip level has %d surfaces attached, expected 1\n", num);
1282     /* Done level 2 */
1283     /* Mip level 3 is still needed */
1284     hr = IDirectDrawSurface7_GetAttachedSurface(surface3, &caps, &surface4);
1285     ok(hr == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", hr);
1286     ok(!surface4, "expected NULL pointer\n");
1287
1288     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1289     memset(&ddsd, 0, sizeof(ddsd));
1290     ddsd.dwSize = sizeof(ddsd);
1291     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1292     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1293     ddsd.dwWidth = 16;
1294     ddsd.dwHeight = 16;
1295     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1296     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1297
1298     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1299     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1300     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1301     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1302     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1303     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1304     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1305     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1306
1307     IDirectDrawSurface7_Release(surface2);
1308
1309     memset(&ddsd, 0, sizeof(ddsd));
1310     ddsd.dwSize = sizeof(ddsd);
1311     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1312     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1313     ddsd.dwWidth = 16;
1314     ddsd.dwHeight = 16;
1315     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1316     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1317
1318     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1319     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1320     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1321     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1322     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1323     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1324     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1325     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1326
1327     IDirectDrawSurface7_Release(surface3);
1328     IDirectDrawSurface7_Release(surface2);
1329     IDirectDrawSurface7_Release(surface1);
1330
1331     hr = IDirectDraw7_SetCooperativeLevel(dd7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1332     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1333
1334     memset(&ddsd, 0, sizeof(ddsd));
1335     ddsd.dwSize = sizeof(ddsd);
1336     ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
1337     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
1338     ddsd.dwBackBufferCount = 2;
1339     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1340     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1341
1342     /* backbuffer surfaces must not have dwBackBufferCount set */
1343     ddsd2.dwSize = sizeof(ddsd2);
1344     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps2, &surface2);
1345     ok(hr==DD_OK,"GetAttachedSurface returned: %x\n", hr);
1346     hr = IDirectDrawSurface7_GetSurfaceDesc(surface2, &ddsd2);
1347     ok(hr==DD_OK,"GetSurfaceDesc returned: %x\n", hr);
1348     ok(ddsd2.dwBackBufferCount==0,"backbuffer surface has dwBackBufferCount==%u\n", ddsd2.dwBackBufferCount);
1349
1350     num = 0;
1351     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1352     ok(num == 1, "Primary surface has %d surfaces attached, expected 1\n", num);
1353     IDirectDrawSurface7_Release(surface1);
1354
1355     /* Those are some invalid descriptions, no need to test attachments with them */
1356     memset(&ddsd, 0, sizeof(ddsd));
1357     ddsd.dwSize = sizeof(ddsd);
1358     ddsd.dwFlags = DDSD_CAPS;
1359     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1360     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1361     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1362     memset(&ddsd, 0, sizeof(ddsd));
1363     ddsd.dwSize = sizeof(ddsd);
1364     ddsd.dwFlags = DDSD_CAPS;
1365     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1366     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1367     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1368
1369     /* Try a single primary and two offscreen plain surfaces */
1370     memset(&ddsd, 0, sizeof(ddsd));
1371     ddsd.dwSize = sizeof(ddsd);
1372     ddsd.dwFlags = DDSD_CAPS;
1373     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1374     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1375     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1376
1377     memset(&ddsd, 0, sizeof(ddsd));
1378     ddsd.dwSize = sizeof(ddsd);
1379     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1380     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1381     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1382     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1383     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1384     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1385
1386     memset(&ddsd, 0, sizeof(ddsd));
1387     ddsd.dwSize = sizeof(ddsd);
1388     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1389     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1390     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1391     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1392     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface3, NULL);
1393     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1394
1395     /* This one has a different size */
1396     memset(&ddsd, 0, sizeof(ddsd));
1397     ddsd.dwSize = sizeof(ddsd);
1398     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1399     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1400     ddsd.dwWidth = 128;
1401     ddsd.dwHeight = 128;
1402     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface4, NULL);
1403     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1404
1405     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1406     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1407     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1408     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1409     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1410     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1411     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1412     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1413     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1414     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1415
1416     IDirectDrawSurface7_Release(surface4);
1417     IDirectDrawSurface7_Release(surface3);
1418     IDirectDrawSurface7_Release(surface2);
1419     IDirectDrawSurface7_Release(surface1);
1420
1421     hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL);
1422     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1423     IDirectDraw7_Release(dd7);
1424 }
1425
1426 static void AttachmentTest(void)
1427 {
1428     HRESULT hr;
1429     IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
1430     DDSURFACEDESC ddsd;
1431     DDSCAPS caps = {DDSCAPS_TEXTURE};
1432     BOOL refrast = FALSE;
1433     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1434
1435     memset(&ddsd, 0, sizeof(ddsd));
1436     ddsd.dwSize = sizeof(ddsd);
1437     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1438     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1439     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1440     ddsd.dwWidth = 128;
1441     ddsd.dwHeight = 128;
1442     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1443     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1444
1445     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1446     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1447     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1448     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1449
1450     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1451     memset(&ddsd, 0, sizeof(ddsd));
1452     ddsd.dwSize = sizeof(ddsd);
1453     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1454     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1455     ddsd.dwWidth = 16;
1456     ddsd.dwHeight = 16;
1457     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1458     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1459
1460     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1461     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1462     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1463     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1464     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
1465     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1466     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1467     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1468     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
1469     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 64x64 texture sublevel returned %08x\n", hr);
1470     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1471     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 texture returned %08x\n", hr);
1472
1473     IDirectDrawSurface7_Release(surface4);
1474
1475     memset(&ddsd, 0, sizeof(ddsd));
1476     ddsd.dwSize = sizeof(ddsd);
1477     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1478     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1479     ddsd.dwWidth = 16;
1480     ddsd.dwHeight = 16;
1481     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1482     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1483
1484     if (SUCCEEDED(IDirectDrawSurface7_AddAttachedSurface(surface1, surface4)))
1485     {
1486         IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1487         refrast = TRUE;
1488     }
1489
1490     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4); /* Succeeds on refrast */
1491     if (refrast)
1492         ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1493     else
1494         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1495     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1496
1497     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);  /* Succeeds on refrast */
1498     if (refrast)
1499         ok(hr == S_OK, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1500     else
1501         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1502     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface1);
1503
1504     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);  /* Succeeds on refrast */
1505     if (refrast)
1506         ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1507     else
1508         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1509     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface3, 0, surface4);
1510
1511     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1512     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1513     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface3);
1514
1515     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);  /* Succeeds on refrast */
1516     if (refrast)
1517         ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1518     else
1519         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1520     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface2, 0, surface4);
1521
1522     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1523     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 offscreen plain surface returned %08x\n", hr);
1524     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface2);
1525
1526     IDirectDrawSurface7_Release(surface4);
1527     IDirectDrawSurface7_Release(surface3);
1528     IDirectDrawSurface7_Release(surface2);
1529     IDirectDrawSurface7_Release(surface1);
1530
1531     hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1532     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1533
1534     /* Creating a back buffer as-is, is not allowed. No need to perform attachment tests */
1535     memset(&ddsd, 0, sizeof(ddsd));
1536     ddsd.dwSize = sizeof(ddsd);
1537     ddsd.dwFlags = DDSD_CAPS;
1538     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1539     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1540     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1541     /* This old ddraw version happily creates explicit front buffers */
1542     memset(&ddsd, 0, sizeof(ddsd));
1543     ddsd.dwSize = sizeof(ddsd);
1544     ddsd.dwFlags = DDSD_CAPS;
1545     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1546     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1547     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1548     IDirectDrawSurface_Release(surface1);
1549
1550     /* Try a single primary and two offscreen plain surfaces */
1551     memset(&ddsd, 0, sizeof(ddsd));
1552     ddsd.dwSize = sizeof(ddsd);
1553     ddsd.dwFlags = DDSD_CAPS;
1554     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1555     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1556     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1557
1558     memset(&ddsd, 0, sizeof(ddsd));
1559     ddsd.dwSize = sizeof(ddsd);
1560     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1561     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1562     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1563     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1564     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1565     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1566
1567     memset(&ddsd, 0, sizeof(ddsd));
1568     ddsd.dwSize = sizeof(ddsd);
1569     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1570     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1571     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1572     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1573     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
1574     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1575
1576     /* This one has a different size */
1577     memset(&ddsd, 0, sizeof(ddsd));
1578     ddsd.dwSize = sizeof(ddsd);
1579     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1580     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1581     ddsd.dwWidth = 128;
1582     ddsd.dwHeight = 128;
1583     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1584     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1585
1586     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
1587     ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1588        "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1589     if(SUCCEEDED(hr))
1590     {
1591         /* Try the reverse without detaching first */
1592         hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1593         ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
1594         hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1595         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1596     }
1597     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1598     ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1599        "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1600     if(SUCCEEDED(hr))
1601     {
1602         /* Try to detach reversed */
1603         hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1604         ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
1605         /* Now the proper detach */
1606         hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
1607         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1608     }
1609     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3); /* Fails on refrast */
1610     ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1611        "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1612     if(SUCCEEDED(hr))
1613     {
1614         hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
1615         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1616     }
1617     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
1618     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1619     hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
1620     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1621
1622     IDirectDrawSurface_Release(surface4);
1623     IDirectDrawSurface_Release(surface3);
1624     IDirectDrawSurface_Release(surface2);
1625     IDirectDrawSurface_Release(surface1);
1626
1627     hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
1628     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1629
1630     DestroyWindow(window);
1631 }
1632
1633 struct compare
1634 {
1635     DWORD width, height;
1636     DWORD caps, caps2;
1637     UINT mips;
1638 };
1639
1640 static HRESULT WINAPI CubeTestPaletteEnum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1641 {
1642     HRESULT hr;
1643
1644     hr = IDirectDrawSurface7_SetPalette(surface, context);
1645     if (desc->dwWidth == 64) /* This is for first mimpmap */
1646         ok(hr == DDERR_NOTONMIPMAPSUBLEVEL, "SetPalette returned: %x\n",hr);
1647     else
1648         ok(hr == DD_OK, "SetPalette returned: %x\n",hr);
1649
1650     IDirectDrawSurface7_Release(surface);
1651
1652     return DDENUMRET_OK;
1653 }
1654
1655 static HRESULT WINAPI CubeTestLvl2Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1656 {
1657     UINT *mips = context;
1658
1659     (*mips)++;
1660     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1661                                              context,
1662                                              CubeTestLvl2Enum);
1663
1664     return DDENUMRET_OK;
1665 }
1666
1667 static HRESULT WINAPI CubeTestLvl1Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1668 {
1669     UINT mips = 0;
1670     UINT *num = context;
1671     static const struct compare expected[] =
1672     {
1673         {
1674             128, 128,
1675             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1676             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ,
1677             7
1678         },
1679         {
1680             128, 128,
1681             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1682             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ,
1683             7
1684         },
1685         {
1686             128, 128,
1687             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1688             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY,
1689             7
1690         },
1691         {
1692             128, 128,
1693             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1694             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY,
1695             7
1696         },
1697         {
1698             128, 128,
1699             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1700             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX,
1701             7
1702         },
1703         {
1704             64, 64, /* This is the first mipmap */
1705             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1706             DDSCAPS2_MIPMAPSUBLEVEL | DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX,
1707             6
1708         },
1709     };
1710
1711     mips = 0;
1712     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1713                                              &mips,
1714                                              CubeTestLvl2Enum);
1715
1716     ok(desc->dwWidth == expected[*num].width, "Surface width is %d expected %d\n", desc->dwWidth, expected[*num].width);
1717     ok(desc->dwHeight == expected[*num].height, "Surface height is %d expected %d\n", desc->dwHeight, expected[*num].height);
1718     ok(desc->ddsCaps.dwCaps == expected[*num].caps, "Surface caps are %08x expected %08x\n", desc->ddsCaps.dwCaps, expected[*num].caps);
1719     ok(desc->ddsCaps.dwCaps2 == expected[*num].caps2, "Surface caps2 are %08x expected %08x\n", desc->ddsCaps.dwCaps2, expected[*num].caps2);
1720     ok(mips == expected[*num].mips, "Surface has %d mipmaps, expected %d\n", mips, expected[*num].mips);
1721
1722     (*num)++;
1723
1724     IDirectDrawSurface7_Release(surface);
1725
1726     return DDENUMRET_OK;
1727 }
1728
1729 static void CubeMapTest(void)
1730 {
1731     IDirectDraw7 *dd7 = NULL;
1732     IDirectDrawSurface7 *cubemap = NULL;
1733     IDirectDrawPalette *palette = NULL;
1734     DDSURFACEDESC2 ddsd;
1735     HRESULT hr;
1736     PALETTEENTRY Table[256];
1737     int i;
1738     UINT num = 0;
1739     UINT ref;
1740     struct enumstruct ctx;
1741
1742     for(i=0; i<256; i++)
1743     {
1744         Table[i].peRed   = 0xff;
1745         Table[i].peGreen = 0;
1746         Table[i].peBlue  = 0;
1747         Table[i].peFlags = 0;
1748     }
1749
1750     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1751     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1752     if (FAILED(hr)) goto err;
1753
1754     memset(&ddsd, 0, sizeof(ddsd));
1755     ddsd.dwSize = sizeof(ddsd);
1756     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1757     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1758     ddsd.dwWidth = 128;
1759     ddsd.dwHeight = 128;
1760     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1761     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1762
1763     /* D3DFMT_R5G6B5 */
1764     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1765     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1766     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1767     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1768     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1769
1770     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1771     if (FAILED(hr))
1772     {
1773         skip("Can't create cubemap surface\n");
1774         goto err;
1775     }
1776
1777     hr = IDirectDrawSurface7_GetSurfaceDesc(cubemap, &ddsd);
1778     ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
1779     ok(ddsd.ddsCaps.dwCaps == (DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX),
1780        "Root Caps are %08x\n", ddsd.ddsCaps.dwCaps);
1781     ok(ddsd.ddsCaps.dwCaps2 == (DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP),
1782        "Root Caps2 are %08x\n", ddsd.ddsCaps.dwCaps2);
1783
1784     IDirectDrawSurface7_EnumAttachedSurfaces(cubemap,
1785                                              &num,
1786                                              CubeTestLvl1Enum);
1787     ok(num == 6, "Surface has %d attachments\n", num);
1788     IDirectDrawSurface7_Release(cubemap);
1789
1790     /* What happens if I do not specify any faces? */
1791     memset(&ddsd, 0, sizeof(ddsd));
1792     ddsd.dwSize = sizeof(ddsd);
1793     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1794     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1795     ddsd.dwWidth = 128;
1796     ddsd.dwHeight = 128;
1797     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1798     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP;
1799
1800     /* D3DFMT_R5G6B5 */
1801     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1802     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1803     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1804     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1805     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1806
1807     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1808     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7::CreateSurface asking for a cube map without faces returned %08x\n", hr);
1809
1810     /* Cube map faces without a cube map? */
1811     memset(&ddsd, 0, sizeof(ddsd));
1812     ddsd.dwSize = sizeof(ddsd);
1813     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1814     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1815     ddsd.dwWidth = 128;
1816     ddsd.dwHeight = 128;
1817     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1818     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_ALLFACES;
1819
1820     /* D3DFMT_R5G6B5 */
1821     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1822     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1823     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1824     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1825     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1826
1827     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1828     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1829
1830     memset(&ddsd, 0, sizeof(ddsd));
1831     ddsd.dwSize = sizeof(ddsd);
1832     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1833     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1834     ddsd.dwWidth = 128;
1835     ddsd.dwHeight = 128;
1836     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1837     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEX;
1838
1839     /* D3DFMT_R5G6B5 */
1840     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1841     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1842     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1843     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1844     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1845
1846     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1847     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1848
1849     memset(&ddsd, 0, sizeof(ddsd));
1850     ddsd.dwSize = sizeof(ddsd);
1851     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1852     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1853     ddsd.dwWidth = 128;
1854     ddsd.dwHeight = 128;
1855     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1856     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1857
1858     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1859     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
1860
1861     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1862     if (FAILED(hr))
1863     {
1864         skip("Can't create palletized cubemap surface\n");
1865         goto err;
1866     }
1867
1868     hr = IDirectDraw7_CreatePalette(dd7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
1869     ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
1870
1871     hr = IDirectDrawSurface7_EnumAttachedSurfaces(cubemap, palette, CubeTestPaletteEnum);
1872     ok(hr == DD_OK, "EnumAttachedSurfaces failed\n");
1873
1874     ref = getRefcount((IUnknown *) palette);
1875     ok(ref == 6, "Refcount is %u, expected 1\n", ref);
1876
1877     IDirectDrawSurface7_Release(cubemap);
1878
1879     ref = getRefcount((IUnknown *) palette);
1880     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1881
1882     IDirectDrawPalette_Release(palette);
1883
1884     /* Make sure everything is cleaned up properly. Use the enumSurfaces test infrastructure */
1885     memset(&ctx, 0, sizeof(ctx));
1886     memset(&ddsd, 0, sizeof(ddsd));
1887     ddsd.dwSize = sizeof(DDSURFACEDESC);
1888     hr = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, (DDSURFACEDESC *) &ddsd, (void *) &ctx, enumCB);
1889     ok(hr == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", hr);
1890     ok(ctx.count == 0, "%d surfaces enumerated, expected 0\n", ctx.count);
1891
1892     err:
1893     if (dd7) IDirectDraw7_Release(dd7);
1894 }
1895
1896 static void test_lockrect_invalid(void)
1897 {
1898     unsigned int i, j;
1899
1900     RECT valid[] = {
1901         {60, 60, 68, 68},
1902         {60, 60, 60, 68},
1903         {60, 60, 68, 60},
1904         {120, 60, 128, 68},
1905         {60, 120, 68, 128},
1906     };
1907
1908     RECT invalid[] = {
1909         {68, 60, 60, 68},       /* left > right */
1910         {60, 68, 68, 60},       /* top > bottom */
1911         {-8, 60,  0, 68},       /* left < surface */
1912         {60, -8, 68,  0},       /* top < surface */
1913         {-16, 60, -8, 68},      /* right < surface */
1914         {60, -16, 68, -8},      /* bottom < surface */
1915         {60, 60, 136, 68},      /* right > surface */
1916         {60, 60, 68, 136},      /* bottom > surface */
1917         {136, 60, 144, 68},     /* left > surface */
1918         {60, 136, 68, 144},     /* top > surface */
1919     };
1920
1921     const DWORD dds_caps[] = {
1922         DDSCAPS_OFFSCREENPLAIN
1923     };
1924
1925     for (j = 0; j < (sizeof(dds_caps) / sizeof(*dds_caps)); ++j)
1926     {
1927         IDirectDrawSurface *surface = 0;
1928         DDSURFACEDESC surface_desc = {0};
1929         DDSURFACEDESC locked_desc = {0};
1930         HRESULT hr;
1931
1932         surface_desc.dwSize = sizeof(surface_desc);
1933         surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
1934         surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1935         surface_desc.ddsCaps.dwCaps = dds_caps[j];
1936         surface_desc.dwWidth = 128;
1937         surface_desc.dwHeight = 128;
1938         surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
1939         U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
1940         U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xFF0000;
1941         U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00FF00;
1942         U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000FF;
1943
1944         hr = IDirectDraw_CreateSurface(lpDD, &surface_desc, &surface, NULL);
1945         ok(SUCCEEDED(hr), "CreateSurface failed (0x%08x)\n", hr);
1946         if (FAILED(hr))
1947         {
1948             skip("failed to create surface\n");
1949             continue;
1950         }
1951
1952         hr = IDirectDrawSurface_Lock(surface, NULL, NULL, DDLOCK_WAIT, NULL);
1953         ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for NULL DDSURFACEDESC,"
1954                 " expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, DDERR_INVALIDPARAMS);
1955
1956         for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i)
1957         {
1958             RECT *rect = &valid[i];
1959
1960             memset(&locked_desc, 0, sizeof(locked_desc));
1961             locked_desc.dwSize = sizeof(locked_desc);
1962
1963             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1964             ok(SUCCEEDED(hr), "Lock failed (0x%08x) for rect [%d, %d]->[%d, %d]\n",
1965                     hr, rect->left, rect->top, rect->right, rect->bottom);
1966
1967             hr = IDirectDrawSurface_Unlock(surface, NULL);
1968             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1969         }
1970
1971         for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i)
1972         {
1973             RECT *rect = &invalid[i];
1974
1975             memset(&locked_desc, 1, sizeof(locked_desc));
1976             locked_desc.dwSize = sizeof(locked_desc);
1977
1978             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1979             ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for rect [%d, %d]->[%d, %d]"
1980                     ", expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, rect->left, rect->top,
1981                     rect->right, rect->bottom, DDERR_INVALIDPARAMS);
1982             ok(!locked_desc.lpSurface, "IDirectDrawSurface_Lock did not set lpSurface in the surface desc to zero.\n");
1983         }
1984
1985         hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1986         ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = NULL) failed (0x%08x)\n", hr);
1987         hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1988         ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned 0x%08x\n", hr);
1989         if(SUCCEEDED(hr)) {
1990             hr = IDirectDrawSurface_Unlock(surface, NULL);
1991             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1992         }
1993         hr = IDirectDrawSurface_Unlock(surface, NULL);
1994         ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1995
1996         memset(&locked_desc, 0, sizeof(locked_desc));
1997         locked_desc.dwSize = sizeof(locked_desc);
1998         hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1999         ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
2000            valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
2001         hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
2002         ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
2003            valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
2004
2005         /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
2006          * Afterwards unlocking the surface fails(NULL rectangle, and both locked rectangles
2007          */
2008
2009         hr = IDirectDrawSurface_Unlock(surface, NULL);
2010         ok(hr == DD_OK, "Unlock returned (0x%08x)\n", hr);
2011
2012         IDirectDrawSurface_Release(surface);
2013     }
2014 }
2015
2016 static void CompressedTest(void)
2017 {
2018     HRESULT hr;
2019     IDirectDrawSurface7 *surface;
2020     DDSURFACEDESC2 ddsd, ddsd2;
2021     IDirectDraw7 *dd7 = NULL;
2022     RECT r = { 0, 0, 128, 128 };
2023     RECT r2 = { 32, 32, 64, 64 };
2024
2025     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2026     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
2027
2028     memset(&ddsd, 0, sizeof(ddsd));
2029     ddsd.dwSize = sizeof(ddsd);
2030     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
2031     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
2032     ddsd.dwWidth = 128;
2033     ddsd.dwHeight = 128;
2034     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
2035     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
2036     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2037
2038     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2039     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2040     if (FAILED(hr))
2041     {
2042         skip("failed to create surface\n");
2043         return;
2044     }
2045
2046     memset(&ddsd2, 0, sizeof(ddsd2));
2047     ddsd2.dwSize = sizeof(ddsd2);
2048     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2049     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2050     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2051
2052     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2053        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2054     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2055     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2056     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2057        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2058     ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2059     ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2060     IDirectDrawSurface7_Release(surface);
2061
2062     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2063     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2064     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2065     if (FAILED(hr))
2066     {
2067         skip("failed to create surface\n");
2068         return;
2069     }
2070
2071     memset(&ddsd2, 0, sizeof(ddsd2));
2072     ddsd2.dwSize = sizeof(ddsd2);
2073     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2074     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2075     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2076
2077     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2078        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2079     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2080     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2081     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2082        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2083     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2084     IDirectDrawSurface7_Release(surface);
2085
2086     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2087     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2088     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2089     if (FAILED(hr))
2090     {
2091         skip("failed to create surface\n");
2092         return;
2093     }
2094
2095     memset(&ddsd2, 0, sizeof(ddsd2));
2096     ddsd2.dwSize = sizeof(ddsd2);
2097     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2098     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2099     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2100
2101     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2102        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2103     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2104     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2105     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2106        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2107     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2108     ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2109
2110     memset(&ddsd2, 0, sizeof(ddsd2));
2111     ddsd2.dwSize = sizeof(ddsd2);
2112     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2113
2114     /* Show that the description is not changed when locking the surface. What is really interesting
2115      * about this is that DDSD_LPSURFACE isn't set.
2116      */
2117     hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2118     ok(hr == DD_OK, "Lock returned %08x\n", hr);
2119
2120     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2121        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2122     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2123     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2124     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2125        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2126     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2127     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2128
2129     hr = IDirectDrawSurface7_Unlock(surface, NULL);
2130     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2131
2132     /* Now what about a locking rect?  */
2133     hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2134     ok(hr == DD_OK, "Lock returned %08x\n", hr);
2135
2136     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2137        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2138     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2139     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2140     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2141        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2142     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2143     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2144
2145     hr = IDirectDrawSurface7_Unlock(surface, &r);
2146     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2147
2148     /* Now what about a different locking offset? */
2149     hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2150     ok(hr == DD_OK, "Lock returned %08x\n", hr);
2151
2152     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2153        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2154     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2155     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2156     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2157        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2158     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2159     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2160
2161     hr = IDirectDrawSurface7_Unlock(surface, &r2);
2162     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2163     IDirectDrawSurface7_Release(surface);
2164
2165     /* Try this with video memory. A kind of surprise. It still has the LINEARSIZE flag set,
2166      * but seems to have a pitch instead.
2167      */
2168     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
2169     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2170
2171     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2172     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW || hr == DDERR_INVALIDPARAMS ||
2173        broken(hr == DDERR_NODIRECTDRAWHW), "CreateSurface returned %08x\n", hr);
2174
2175     /* Not supported everywhere */
2176     if(SUCCEEDED(hr))
2177     {
2178         memset(&ddsd2, 0, sizeof(ddsd2));
2179         ddsd2.dwSize = sizeof(ddsd2);
2180         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2181         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2182         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2183
2184         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2185         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2186         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2187         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2188         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2189         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2190         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2191         ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2192         IDirectDrawSurface7_Release(surface);
2193
2194         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2195         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2196         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2197
2198         memset(&ddsd2, 0, sizeof(ddsd2));
2199         ddsd2.dwSize = sizeof(ddsd2);
2200         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2201         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2202         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2203
2204         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2205         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2206         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2207         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2208         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2209         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2210         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2211         IDirectDrawSurface7_Release(surface);
2212
2213         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2214         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2215         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2216
2217         memset(&ddsd2, 0, sizeof(ddsd2));
2218         ddsd2.dwSize = sizeof(ddsd2);
2219         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2220         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2221         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2222
2223         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2224         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2225         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2226         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2227         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2228         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2229         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2230         ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2231
2232         memset(&ddsd2, 0, sizeof(ddsd2));
2233         ddsd2.dwSize = sizeof(ddsd2);
2234         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2235
2236         /* Show that the description is not changed when locking the surface. What is really interesting
2237         * about this is that DDSD_LPSURFACE isn't set.
2238         */
2239         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2240         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2241
2242         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2243         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2244         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2245         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2246         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2247         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2248         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2249         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2250
2251         hr = IDirectDrawSurface7_Unlock(surface, NULL);
2252         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2253
2254         /* Now what about a locking rect?  */
2255         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2256         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2257
2258         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2259         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2260         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2261         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2262         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2263         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2264         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2265         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2266
2267         hr = IDirectDrawSurface7_Unlock(surface, &r);
2268         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2269
2270         /* Now what about a different locking offset? */
2271         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2272         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2273
2274         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2275         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2276         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2277         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2278         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2279         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2280         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2281         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2282
2283         hr = IDirectDrawSurface7_Unlock(surface, &r2);
2284         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2285
2286         IDirectDrawSurface7_Release(surface);
2287     }
2288     else
2289     {
2290         skip("Hardware DXTN textures not supported\n");
2291     }
2292
2293     /* What happens to managed textures? Interestingly, Windows reports them as being in system
2294      * memory. The linear size fits again.
2295      */
2296     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2297     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
2298     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2299
2300     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2301     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW, "CreateSurface returned %08x\n", hr);
2302
2303     /* Not supported everywhere */
2304     if(SUCCEEDED(hr))
2305     {
2306         memset(&ddsd2, 0, sizeof(ddsd2));
2307         ddsd2.dwSize = sizeof(ddsd2);
2308         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2309         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2310         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2311
2312         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2313         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2314         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2315         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2316         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2317         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2318         ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2319         ok(ddsd2.ddsCaps.dwCaps2 == DDSCAPS2_TEXTUREMANAGE, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2320         IDirectDrawSurface7_Release(surface);
2321
2322         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2323         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2324         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2325
2326         memset(&ddsd2, 0, sizeof(ddsd2));
2327         ddsd2.dwSize = sizeof(ddsd2);
2328         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2329         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2330         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2331
2332         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2333         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2334         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2335         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2336         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2337         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2338         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2339         IDirectDrawSurface7_Release(surface);
2340
2341         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2342         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2343         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2344
2345         memset(&ddsd2, 0, sizeof(ddsd2));
2346         ddsd2.dwSize = sizeof(ddsd2);
2347         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2348         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2349         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2350
2351         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2352         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2353         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2354         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2355         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2356         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2357         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2358         ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2359
2360         memset(&ddsd2, 0, sizeof(ddsd2));
2361         ddsd2.dwSize = sizeof(ddsd2);
2362         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2363
2364         /* Show that the description is not changed when locking the surface. What is really interesting
2365         * about this is that DDSD_LPSURFACE isn't set.
2366         */
2367         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2368         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2369
2370         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2371         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2372         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2373         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2374         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2375         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2376         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2377         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2378
2379         hr = IDirectDrawSurface7_Unlock(surface, NULL);
2380         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2381
2382         /* Now what about a locking rect?  */
2383         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2384         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2385
2386         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2387         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2388         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2389         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2390         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2391         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2392         ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2393         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2394
2395         hr = IDirectDrawSurface7_Unlock(surface, &r);
2396         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2397
2398         /* Now what about a different locking offset? */
2399         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2400         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2401
2402         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2403         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2404         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2405         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2406         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2407         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2408         ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2409         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2410
2411         hr = IDirectDrawSurface7_Unlock(surface, &r2);
2412         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2413
2414         IDirectDrawSurface7_Release(surface);
2415     }
2416     else
2417     {
2418         skip("Hardware DXTN textures not supported\n");
2419     }
2420
2421     IDirectDraw7_Release(dd7);
2422 }
2423
2424 static void SizeTest(void)
2425 {
2426     LPDIRECTDRAWSURFACE dsurface = NULL;
2427     DDSURFACEDESC desc;
2428     HRESULT ret;
2429     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2430
2431     /* Create an offscreen surface surface without a size */
2432     ZeroMemory(&desc, sizeof(desc));
2433     desc.dwSize = sizeof(desc);
2434     desc.dwFlags = DDSD_CAPS;
2435     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2436     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2437     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without a size info returned %08x (dsurface=%p)\n", ret, dsurface);
2438     if(dsurface)
2439     {
2440         trace("Surface at %p\n", dsurface);
2441         IDirectDrawSurface_Release(dsurface);
2442         dsurface = NULL;
2443     }
2444
2445     /* Create an offscreen surface surface with only a width parameter */
2446     ZeroMemory(&desc, sizeof(desc));
2447     desc.dwSize = sizeof(desc);
2448     desc.dwFlags = DDSD_CAPS | DDSD_WIDTH;
2449     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2450     desc.dwWidth = 128;
2451     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2452     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without height info returned %08x\n", ret);
2453     if(dsurface)
2454     {
2455         IDirectDrawSurface_Release(dsurface);
2456         dsurface = NULL;
2457     }
2458
2459     /* Create an offscreen surface surface with only a height parameter */
2460     ZeroMemory(&desc, sizeof(desc));
2461     desc.dwSize = sizeof(desc);
2462     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT;
2463     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2464     desc.dwHeight = 128;
2465     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2466     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without width info returned %08x\n", ret);
2467     if(dsurface)
2468     {
2469         IDirectDrawSurface_Release(dsurface);
2470         dsurface = NULL;
2471     }
2472
2473     /* Test 0 height. */
2474     memset(&desc, 0, sizeof(desc));
2475     desc.dwSize = sizeof(desc);
2476     desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2477     desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2478     desc.dwWidth = 1;
2479     desc.dwHeight = 0;
2480     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2481     ok(ret == DDERR_INVALIDPARAMS, "Creating a 0 height surface returned %#x, expected DDERR_INVALIDPARAMS.\n", ret);
2482     if (SUCCEEDED(ret)) IDirectDrawSurface_Release(dsurface);
2483     dsurface = NULL;
2484
2485     /* Test 0 width. */
2486     memset(&desc, 0, sizeof(desc));
2487     desc.dwSize = sizeof(desc);
2488     desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2489     desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2490     desc.dwWidth = 0;
2491     desc.dwHeight = 1;
2492     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2493     ok(ret == DDERR_INVALIDPARAMS, "Creating a 0 width surface returned %#x, expected DDERR_INVALIDPARAMS.\n", ret);
2494     if (SUCCEEDED(ret)) IDirectDrawSurface_Release(dsurface);
2495     dsurface = NULL;
2496
2497     /* Sanity check */
2498     ZeroMemory(&desc, sizeof(desc));
2499     desc.dwSize = sizeof(desc);
2500     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2501     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2502     desc.dwHeight = 128;
2503     desc.dwWidth = 128;
2504     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2505     ok(ret == DD_OK, "Creating an offscreen plain surface with width and height info returned %08x\n", ret);
2506     if(dsurface)
2507     {
2508         IDirectDrawSurface_Release(dsurface);
2509         dsurface = NULL;
2510     }
2511
2512     /* Test a primary surface size */
2513     ret = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_NORMAL);
2514     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2515
2516     ZeroMemory(&desc, sizeof(desc));
2517     desc.dwSize = sizeof(desc);
2518     desc.dwFlags = DDSD_CAPS;
2519     desc.ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
2520     desc.dwHeight = 128; /* Keep them set to  check what happens */
2521     desc.dwWidth = 128; /* Keep them set to  check what happens */
2522     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2523     ok(ret == DD_OK, "Creating a primary surface without width and height info returned %08x\n", ret);
2524     if(dsurface)
2525     {
2526         ret = IDirectDrawSurface_GetSurfaceDesc(dsurface, &desc);
2527         ok(ret == DD_OK, "GetSurfaceDesc returned %x\n", ret);
2528
2529         IDirectDrawSurface_Release(dsurface);
2530         dsurface = NULL;
2531
2532         ok(desc.dwFlags & DDSD_WIDTH, "Primary surface doesn't have width set\n");
2533         ok(desc.dwFlags & DDSD_HEIGHT, "Primary surface doesn't have height set\n");
2534         ok(desc.dwWidth == GetSystemMetrics(SM_CXSCREEN), "Surface width differs from screen width\n");
2535         ok(desc.dwHeight == GetSystemMetrics(SM_CYSCREEN), "Surface height differs from screen height\n");
2536     }
2537     ret = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
2538     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2539 }
2540
2541 static void PrivateDataTest(void)
2542 {
2543     HRESULT hr;
2544     IDirectDrawSurface7 *surface7 = NULL;
2545     IDirectDrawSurface *surface = NULL;
2546     DDSURFACEDESC desc;
2547     ULONG ref, ref2;
2548     IUnknown *ptr;
2549     DWORD size = sizeof(IUnknown *);
2550
2551     ZeroMemory(&desc, sizeof(desc));
2552     desc.dwSize = sizeof(desc);
2553     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2554     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2555     desc.dwHeight = 128;
2556     desc.dwWidth = 128;
2557     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface, NULL);
2558     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2559     if(!surface)
2560     {
2561         return;
2562     }
2563     hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **) &surface7);
2564     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2565     if(!surface7)
2566     {
2567         IDirectDrawSurface_Release(surface);
2568         return;
2569     }
2570
2571     /* This fails */
2572     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 0, DDSPD_IUNKNOWNPOINTER);
2573     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2574     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 5, DDSPD_IUNKNOWNPOINTER);
2575     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2576     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *) * 2, DDSPD_IUNKNOWNPOINTER);
2577     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2578
2579     ref = getref((IUnknown *) lpDD);
2580     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2581     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2582     ref2 = getref((IUnknown *) lpDD);
2583     ok(ref2 == ref + 1, "Object reference is %d, expected %d\n", ref2, ref + 1);
2584     hr = IDirectDrawSurface7_FreePrivateData(surface7, &IID_IDirectDrawSurface7);
2585     ok(SUCCEEDED(hr), "IDirectDrawSurface7_FreePrivateData returned %#x.\n", hr);
2586     ref2 = getref((IUnknown *) lpDD);
2587     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2588
2589     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2590     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2591     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, surface7, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2592     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2593     ref2 = getref((IUnknown *) lpDD);
2594     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2595
2596     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2597     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2598     hr = IDirectDrawSurface7_GetPrivateData(surface7, &IID_IDirectDrawSurface7, &ptr, &size);
2599     ok(hr == DD_OK, "IDirectDrawSurface7_GetPrivateData failed with %08x\n", hr);
2600     ref2 = getref((IUnknown *) lpDD);
2601     /* Object is NOT being addrefed */
2602     ok(ptr == (IUnknown *) lpDD, "Returned interface pointer is %p, expected %p\n", ptr, lpDD);
2603     ok(ref2 == ref + 1, "Object reference is %d, expected %d. ptr at %p, orig at %p\n", ref2, ref + 1, ptr, lpDD);
2604
2605     IDirectDrawSurface_Release(surface);
2606     IDirectDrawSurface7_Release(surface7);
2607
2608     /* Destroying the surface frees the held reference */
2609     ref2 = getref((IUnknown *) lpDD);
2610     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2611 }
2612
2613 static void BltParamTest(void)
2614 {
2615     IDirectDrawSurface *surface1 = NULL, *surface2 = NULL;
2616     DDSURFACEDESC desc;
2617     HRESULT hr;
2618     DDBLTFX BltFx;
2619     RECT valid = {10, 10, 20, 20};
2620     RECT invalid1 = {20, 10, 10, 20};
2621     RECT invalid2 = {20, 20, 20, 20};
2622     RECT invalid3 = {-1, -1, 20, 20};
2623     RECT invalid4 = {60, 60, 70, 70};
2624
2625     memset(&desc, 0, sizeof(desc));
2626     desc.dwSize = sizeof(desc);
2627     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2628     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2629     desc.dwHeight = 128;
2630     desc.dwWidth = 128;
2631     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface1, NULL);
2632     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2633
2634     desc.dwHeight = 64;
2635     desc.dwWidth = 64;
2636     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface2, NULL);
2637     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2638
2639     if(0)
2640     {
2641         /* This crashes */
2642         hr = IDirectDrawSurface_BltFast(surface1, 0, 0, NULL, NULL, 0);
2643         ok(hr == DD_OK, "BltFast from NULL surface returned %08x\n", hr);
2644     }
2645     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, NULL, 0);
2646     ok(hr == DD_OK, "BltFast from smaller to bigger surface returned %08x\n", hr);
2647     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, NULL, 0);
2648     ok(hr == DDERR_INVALIDRECT, "BltFast from bigger to smaller surface returned %08x\n", hr);
2649     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &valid, 0);
2650     ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle returned %08x\n", hr);
2651     hr = IDirectDrawSurface_BltFast(surface2, 60, 60, surface1, &valid, 0);
2652     ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2653     hr = IDirectDrawSurface_BltFast(surface1, 90, 90, surface2, NULL, 0);
2654     ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2655
2656     hr = IDirectDrawSurface_BltFast(surface1, -10, 0, surface2, NULL, 0);
2657     ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
2658     hr = IDirectDrawSurface_BltFast(surface1, 0, -10, surface2, NULL, 0);
2659     ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
2660     hr = IDirectDrawSurface_BltFast(surface2, 20, 20, surface1, &valid, 0);
2661     ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle and offset returned %08x\n", hr);
2662
2663     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid1, 0);
2664     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 1 returned %08x\n", hr);
2665     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid2, 0);
2666     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 2 returned %08x\n", hr);
2667     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid3, 0);
2668     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2669     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, &invalid4, 0);
2670     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2671     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface1, NULL, 0);
2672     ok(hr == DD_OK, "BltFast blitting a surface onto itself returned %08x\n", hr);
2673
2674     /* Blt(non-fast) tests */
2675     memset(&BltFx, 0, sizeof(BltFx));
2676     BltFx.dwSize = sizeof(BltFx);
2677     U5(BltFx).dwFillColor = 0xaabbccdd;
2678
2679     hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2680     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a valid rectangle for color fill returned %08x\n", hr);
2681     hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, &invalid3, DDBLT_COLORFILL, &BltFx);
2682     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a invalid, unused rectangle returned %08x\n", hr);
2683     hr = IDirectDrawSurface_Blt(surface2, &invalid1, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2684     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2685     hr = IDirectDrawSurface_Blt(surface2, &invalid2, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2686     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2687     hr = IDirectDrawSurface_Blt(surface2, &invalid3, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2688     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2689     hr = IDirectDrawSurface_Blt(surface2, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2690     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2691
2692     /* Valid on surface 1 */
2693     hr = IDirectDrawSurface_Blt(surface1, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2694     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a subrectangle fill returned %08x\n", hr);
2695
2696     /* Works - stretched blit */
2697     hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, NULL, 0, NULL);
2698     ok(hr == DD_OK, "IDirectDrawSurface_Blt from a smaller to a bigger surface returned %08x\n", hr);
2699     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, NULL, 0, NULL);
2700     ok(hr == DD_OK, "IDirectDrawSurface_Blt from a bigger to a smaller surface %08x\n", hr);
2701
2702     /* Invalid dest rects in sourced blits */
2703     hr = IDirectDrawSurface_Blt(surface2, &invalid1, surface1, NULL, 0, NULL);
2704     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2705     hr = IDirectDrawSurface_Blt(surface2, &invalid2, surface1, NULL, 0, NULL);
2706     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2707     hr = IDirectDrawSurface_Blt(surface2, &invalid3, surface1, NULL, 0, NULL);
2708     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2709     hr = IDirectDrawSurface_Blt(surface2, &invalid4, surface1, NULL, 0, NULL);
2710     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2711
2712     /* Invalid src rects */
2713     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid1, 0, NULL);
2714     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2715     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid2, 0, NULL);
2716     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2717     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid3, 0, NULL);
2718     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2719     hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, &invalid4, 0, NULL);
2720     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2721
2722     IDirectDrawSurface_Release(surface1);
2723     IDirectDrawSurface_Release(surface2);
2724 }
2725
2726 static void PaletteTest(void)
2727 {
2728     HRESULT hr;
2729     LPDIRECTDRAWSURFACE lpSurf = NULL;
2730     IDirectDrawSurface *backbuffer = NULL;
2731     DDSCAPS ddscaps;
2732     DDSURFACEDESC ddsd;
2733     IDirectDrawPalette *palette = NULL;
2734     PALETTEENTRY Table[256];
2735     PALETTEENTRY palEntries[256];
2736     int i;
2737
2738     for(i=0; i<256; i++)
2739     {
2740         Table[i].peRed   = 0xff;
2741         Table[i].peGreen = 0;
2742         Table[i].peBlue  = 0;
2743         Table[i].peFlags = 0;
2744     }
2745
2746     /* Create a 8bit palette without DDPCAPS_ALLOW256 set */
2747     hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_8BIT, Table, &palette, NULL);
2748     ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2749     if (FAILED(hr)) goto err;
2750     /* Read back the palette and verify the entries. Without DDPCAPS_ALLOW256 set
2751     /  entry 0 and 255 should have been overwritten with black and white */
2752     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2753     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2754     if(hr == DD_OK)
2755     {
2756         ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2757            "Palette entry 0 of a palette without DDPCAPS_ALLOW256 set should be (0,0,0) but it is (%d,%d,%d)\n",
2758            palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2759         ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2760            "Palette entry 255 of a palette without DDPCAPS_ALLOW256 set should be (255,255,255) but it is (%d,%d,%d)\n",
2761            palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2762
2763         /* Entry 1-254 should contain red */
2764         for(i=1; i<255; i++)
2765             ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2766                "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2767                i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2768     }
2769
2770     /* CreatePalette without DDPCAPS_ALLOW256 ignores entry 0 and 255,
2771     /  now check we are able to update the entries afterwards. */
2772     IDirectDrawPalette_SetEntries(palette , 0, 0, 256, &Table[0]);
2773     ok(hr == DD_OK, "SetEntries failed with %08x\n", hr);
2774     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2775     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2776     if(hr == DD_OK)
2777     {
2778         ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2779            "Palette entry 0 should have been set to (0,0,0) but it contains (%d,%d,%d)\n",
2780            palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2781         ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2782            "Palette entry 255 should have been set to (255,255,255) but it contains (%d,%d,%d)\n",
2783            palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2784     }
2785     IDirectDrawPalette_Release(palette);
2786
2787     /* Create a 8bit palette with DDPCAPS_ALLOW256 set */
2788     hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
2789     ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2790     if (FAILED(hr)) goto err;
2791
2792     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2793     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2794     if(hr == DD_OK)
2795     {
2796         /* All entries should contain red */
2797         for(i=0; i<256; i++)
2798             ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2799                "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2800                i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2801     }
2802
2803     /* Try to set palette to a non-palettized surface */
2804     ddsd.dwSize = sizeof(ddsd);
2805     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2806     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2807     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2808     ddsd.dwWidth = 800;
2809     ddsd.dwHeight = 600;
2810     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2811     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
2812     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
2813     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
2814     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
2815     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurf, NULL);
2816     ok(hr==DD_OK, "CreateSurface returned: %x\n",hr);
2817     if (FAILED(hr))
2818     {
2819         skip("failed to create surface\n");
2820         goto err;
2821     }
2822
2823     hr = IDirectDrawSurface_SetPalette(lpSurf, palette);
2824     ok(hr == DDERR_INVALIDPIXELFORMAT, "CreateSurface returned: %x\n",hr);
2825
2826     IDirectDrawPalette_Release(palette);
2827     palette = NULL;
2828
2829     hr = IDirectDrawSurface_GetPalette(lpSurf, &palette);
2830     ok(hr == DDERR_NOPALETTEATTACHED, "CreateSurface returned: %x\n",hr);
2831
2832     err:
2833
2834     if (lpSurf) IDirectDrawSurface_Release(lpSurf);
2835     if (palette) IDirectDrawPalette_Release(palette);
2836
2837     hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
2838     ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2839
2840     ddsd.dwSize = sizeof(ddsd);
2841     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2842     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_BACKBUFFERCOUNT;
2843     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
2844     ddsd.dwWidth = 64;
2845     ddsd.dwHeight = 64;
2846     ddsd.dwBackBufferCount = 1;
2847     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
2848     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
2849
2850     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurf, NULL);
2851     ok(hr==DD_OK, "CreateSurface returned: %x\n",hr);
2852     if (FAILED(hr))
2853     {
2854         skip("failed to create surface\n");
2855         return;
2856     }
2857
2858     ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
2859     hr = IDirectDrawSurface_GetAttachedSurface(lpSurf, &ddscaps, &backbuffer);
2860     ok(hr == DD_OK, "GetAttachedSurface returned: %x\n",hr);
2861
2862     hr = IDirectDrawSurface_SetPalette(backbuffer, palette);
2863     ok(hr == DD_OK, "SetPalette returned: %x\n",hr);
2864
2865     IDirectDrawPalette_Release(palette);
2866     palette = NULL;
2867
2868     hr = IDirectDrawSurface_GetPalette(backbuffer, &palette);
2869     ok(hr == DD_OK, "CreateSurface returned: %x\n",hr);
2870
2871     IDirectDrawSurface_Release(backbuffer);
2872     IDirectDrawSurface_Release(lpSurf);
2873 }
2874
2875 static void StructSizeTest(void)
2876 {
2877     IDirectDrawSurface *surface1;
2878     IDirectDrawSurface7 *surface7;
2879     union {
2880         DDSURFACEDESC desc1;
2881         DDSURFACEDESC2 desc2;
2882         char blob[1024]; /* To get a bunch of writable memory */
2883     } desc;
2884     DDSURFACEDESC create;
2885     HRESULT hr;
2886
2887     memset(&desc, 0, sizeof(desc));
2888     memset(&create, 0, sizeof(create));
2889
2890     memset(&create, 0, sizeof(create));
2891     create.dwSize = sizeof(create);
2892     create.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2893     create.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2894     create.dwHeight = 128;
2895     create.dwWidth = 128;
2896     hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2897     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2898     hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface7, (void **) &surface7);
2899     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2900
2901     desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2902     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2903     ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2904     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2905     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2906
2907     desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2908     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2909     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2910     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2911     ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2912
2913     desc.desc2.dwSize = 0;
2914     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2915     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2916     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2917     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2918
2919     desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2920     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2921     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2922     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2923     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2924
2925     desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2926     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2927     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2928     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2929     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2930
2931     /* Tests for Lock() */
2932
2933     desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2934     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2935     ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2936     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2937     ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2938     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2939     ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2940     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2941     ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2942
2943     desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2944     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2945     ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2946     ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2947     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2948     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2949     ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2950     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2951     ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2952
2953     desc.desc2.dwSize = 0;
2954     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2955     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size 0 returned %08x\n", hr);
2956     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2957     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2958     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size 0 returned %08x\n", hr);
2959     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2960
2961     desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2962     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2963     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2964     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2965     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2966     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2967     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2968
2969     desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2970     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2971     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2972     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2973     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2974     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2975     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2976
2977     IDirectDrawSurface7_Release(surface7);
2978     IDirectDrawSurface_Release(surface1);
2979 }
2980
2981 static void SurfaceCapsTest(void)
2982 {
2983     DDSURFACEDESC create;
2984     DDSURFACEDESC desc;
2985     HRESULT hr;
2986     IDirectDrawSurface *surface1 = NULL;
2987     DDSURFACEDESC2 create2, desc2;
2988     IDirectDrawSurface7 *surface7 = NULL;
2989     IDirectDraw7 *dd7 = NULL;
2990     DWORD create_caps[] = {
2991         DDSCAPS_OFFSCREENPLAIN,
2992         DDSCAPS_TEXTURE,
2993         DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD,
2994         0,
2995         DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2996         DDSCAPS_PRIMARYSURFACE,
2997         DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY,
2998         DDSCAPS_3DDEVICE,
2999         DDSCAPS_ZBUFFER,
3000         DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN
3001     };
3002     DWORD expected_caps[] = {
3003         DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
3004         DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
3005         DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD,
3006         DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
3007         DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
3008         DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_VISIBLE,
3009         DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_VISIBLE,
3010         DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
3011         DDSCAPS_ZBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY,
3012         DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM
3013     };
3014     UINT i;
3015
3016     /* Tests various surface flags, what changes do they undergo during surface creation. Forsaken
3017      * engine expects texture surfaces without memory flag to get a video memory flag right after
3018      * creation. Currently, Wine adds DDSCAPS_FRONTBUFFER to primary surface, but native doesn't do this
3019      * for single buffered primaries. Because of this primary surface creation tests are todo_wine. No real
3020      * app is known so far to care about this. */
3021
3022     if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3023     {
3024         skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3025         return ;
3026     }
3027
3028     for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
3029     {
3030         memset(&create, 0, sizeof(create));
3031         create.dwSize = sizeof(create);
3032         create.ddsCaps.dwCaps = create_caps[i];
3033         create.dwFlags = DDSD_CAPS;
3034
3035         if (!(create.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
3036         {
3037             create.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
3038             create.dwHeight = 128;
3039             create.dwWidth = 128;
3040         }
3041
3042         if (create.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
3043         {
3044             create.dwFlags |= DDSD_PIXELFORMAT;
3045             create.ddpfPixelFormat.dwSize = sizeof(create.ddpfPixelFormat);
3046             create.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3047             U1(create.ddpfPixelFormat).dwZBufferBitDepth = 16;
3048             U3(create.ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3049         }
3050
3051         hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
3052         ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
3053
3054         if (SUCCEEDED(hr))
3055         {
3056             memset(&desc, 0, sizeof(desc));
3057             desc.dwSize = sizeof(DDSURFACEDESC);
3058             hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc);
3059             ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
3060
3061             if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
3062                 ok(desc.ddsCaps.dwCaps == expected_caps[i],
3063                     "GetSurfaceDesc test %d returned caps %x, expected %x\n", i,
3064                     desc.ddsCaps.dwCaps, expected_caps[i]);
3065             else
3066                 todo_wine ok(desc.ddsCaps.dwCaps == expected_caps[i],
3067                                 "GetSurfaceDesc test %d returned caps %x, expected %x\n", i,
3068                                 desc.ddsCaps.dwCaps, expected_caps[i]);
3069
3070             IDirectDrawSurface_Release(surface1);
3071         }
3072     }
3073
3074     /* Test for differences in ddraw 7 */
3075     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3076     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
3077     if (FAILED(hr))
3078     {
3079         skip("Failed to get IDirectDraw7 interface, skipping tests\n");
3080     }
3081     else
3082     {
3083         for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
3084         {
3085             memset(&create2, 0, sizeof(create2));
3086             create2.dwSize = sizeof(create2);
3087             create2.ddsCaps.dwCaps = create_caps[i];
3088             create2.dwFlags = DDSD_CAPS;
3089
3090             if (!(create2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
3091             {
3092                 create2.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
3093                 create2.dwHeight = 128;
3094                 create2.dwWidth = 128;
3095             }
3096
3097             if (create2.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
3098             {
3099                 create2.dwFlags |= DDSD_PIXELFORMAT;
3100                 U4(create2).ddpfPixelFormat.dwSize = sizeof(U4(create2).ddpfPixelFormat);
3101                 U4(create2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
3102                 U1(U4(create2).ddpfPixelFormat).dwZBufferBitDepth = 16;
3103                 U3(U4(create2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
3104             }
3105
3106             hr = IDirectDraw7_CreateSurface(dd7, &create2, &surface7, NULL);
3107             ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3108
3109             if (SUCCEEDED(hr))
3110             {
3111                 memset(&desc2, 0, sizeof(desc2));
3112                 desc2.dwSize = sizeof(DDSURFACEDESC2);
3113                 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc2);
3114                 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
3115
3116                 if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
3117                     ok(desc2.ddsCaps.dwCaps == expected_caps[i],
3118                         "GetSurfaceDesc test %d returned caps %x, expected %x\n", i,
3119                         desc2.ddsCaps.dwCaps, expected_caps[i]);
3120                 else
3121                     todo_wine ok(desc2.ddsCaps.dwCaps == expected_caps[i],
3122                                     "GetSurfaceDesc test %d returned caps %x, expected %x\n", i,
3123                                     desc2.ddsCaps.dwCaps, expected_caps[i]);
3124
3125                 IDirectDrawSurface7_Release(surface7);
3126             }
3127         }
3128
3129         IDirectDraw7_Release(dd7);
3130     }
3131
3132     memset(&create, 0, sizeof(create));
3133     create.dwSize = sizeof(create);
3134     create.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3135     create.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY;
3136     create.dwWidth = 64;
3137     create.dwHeight = 64;
3138     hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
3139     ok(hr == DDERR_INVALIDCAPS, "Creating a SYSMEM | VIDMEM surface returned 0x%08x, expected DDERR_INVALIDCAPS\n", hr);
3140     if(surface1) IDirectDrawSurface_Release(surface1);
3141 }
3142
3143 static BOOL can_create_primary_surface(void)
3144 {
3145     DDSURFACEDESC ddsd;
3146     IDirectDrawSurface *surface;
3147     HRESULT hr;
3148
3149     memset(&ddsd, 0, sizeof(ddsd));
3150     ddsd.dwSize = sizeof(ddsd);
3151     ddsd.dwFlags = DDSD_CAPS;
3152     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3153     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3154     if(FAILED(hr)) return FALSE;
3155     IDirectDrawSurface_Release(surface);
3156     return TRUE;
3157 }
3158
3159 static void dctest_surf(IDirectDrawSurface *surf, int ddsdver) {
3160     HRESULT hr;
3161     HDC dc, dc2 = (HDC) 0x1234;
3162     DDSURFACEDESC ddsd;
3163     DDSURFACEDESC2 ddsd2;
3164
3165     memset(&ddsd, 0, sizeof(ddsd));
3166     ddsd.dwSize = sizeof(ddsd);
3167     memset(&ddsd2, 0, sizeof(ddsd2));
3168     ddsd2.dwSize = sizeof(ddsd2);
3169
3170     hr = IDirectDrawSurface_GetDC(surf, &dc);
3171     ok(hr == DD_OK, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
3172
3173     hr = IDirectDrawSurface_GetDC(surf, &dc2);
3174     ok(hr == DDERR_DCALREADYCREATED, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
3175     ok(dc2 == (HDC) 0x1234, "The failed GetDC call changed the dc: %p\n", dc2);
3176
3177     hr = IDirectDrawSurface_Lock(surf, NULL, ddsdver == 1 ? &ddsd : ((DDSURFACEDESC *) &ddsd2), 0, NULL);
3178     ok(hr == DDERR_SURFACEBUSY, "IDirectDrawSurface_Lock returned 0x%08x, expected DDERR_ALREADYLOCKED\n", hr);
3179
3180     hr = IDirectDrawSurface_ReleaseDC(surf, dc);
3181     ok(hr == DD_OK, "IDirectDrawSurface_ReleaseDC failed: 0x%08x\n", hr);
3182     hr = IDirectDrawSurface_ReleaseDC(surf, dc);
3183     ok(hr == DDERR_NODC, "IDirectDrawSurface_ReleaseDC returned 0x%08x, expected DDERR_NODC\n", hr);
3184 }
3185
3186 static void GetDCTest(void)
3187 {
3188     DDSURFACEDESC ddsd;
3189     DDSURFACEDESC2 ddsd2;
3190     IDirectDrawSurface *surf;
3191     IDirectDrawSurface2 *surf2;
3192     IDirectDrawSurface4 *surf4;
3193     IDirectDrawSurface7 *surf7;
3194     IDirectDrawSurface *tmp;
3195     IDirectDrawSurface7 *tmp7;
3196     HRESULT hr;
3197     IDirectDraw2 *dd2;
3198     IDirectDraw4 *dd4;
3199     IDirectDraw7 *dd7;
3200     HDC dc;
3201     ULONG ref;
3202
3203     memset(&ddsd, 0, sizeof(ddsd));
3204     ddsd.dwSize = sizeof(ddsd);
3205     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3206     ddsd.dwWidth = 64;
3207     ddsd.dwHeight = 64;
3208     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3209     memset(&ddsd2, 0, sizeof(ddsd2));
3210     ddsd2.dwSize = sizeof(ddsd2);
3211     ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3212     ddsd2.dwWidth = 64;
3213     ddsd2.dwHeight = 64;
3214     ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3215
3216     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
3217     ok(hr == DD_OK, "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3218     dctest_surf(surf, 1);
3219     IDirectDrawSurface_Release(surf);
3220
3221     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3222     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3223
3224     hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3225     ok(hr == DD_OK, "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
3226     dctest_surf(surf, 1);
3227
3228     hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
3229     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr);
3230     dctest_surf((IDirectDrawSurface *) surf2, 1);
3231
3232     IDirectDrawSurface2_Release(surf2);
3233     IDirectDrawSurface_Release(surf);
3234     IDirectDraw2_Release(dd2);
3235
3236     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3237     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3238
3239     surf = NULL;
3240     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3241     ok(hr == DD_OK, "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
3242     dctest_surf((IDirectDrawSurface *) surf4, 2);
3243
3244     hr = IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)&surf);
3245     ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3246
3247     ref = getRefcount((IUnknown *) surf);
3248     ok(ref == 1, "Refcount is %u, expected 1\n", ref);
3249     ref = getRefcount((IUnknown *) surf4);
3250     ok(ref == 1, "Refcount is %u, expected 1\n", ref);
3251
3252     hr = IDirectDrawSurface4_GetDC(surf4, &dc);
3253     ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
3254
3255     hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, NULL);
3256     ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
3257
3258     hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
3259     ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
3260     ok(tmp == surf, "Expected surface %p, got %p.\n\n", surf, tmp);
3261
3262     ref = getRefcount((IUnknown *) surf);
3263     ok(ref == 2, "Refcount is %u, expected 2\n", ref);
3264     ref = getRefcount((IUnknown *) tmp);
3265     ok(ref == 2, "Refcount is %u, expected 2\n", ref);
3266     ref = getRefcount((IUnknown *) surf4);
3267     ok(ref == 1, "Refcount is %u, expected 1\n", ref);
3268
3269     hr = IDirectDrawSurface4_ReleaseDC(surf4, dc);
3270     ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
3271
3272     IDirectDrawSurface_Release(tmp);
3273
3274     dc = CreateCompatibleDC(NULL);
3275     ok(!!dc, "CreateCompatibleDC failed.\n");
3276
3277     tmp = (IDirectDrawSurface *)0xdeadbeef;
3278     hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
3279     ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3280     ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
3281
3282     ok(DeleteDC(dc), "DeleteDC failed.\n");
3283
3284     tmp = (IDirectDrawSurface *)0xdeadbeef;
3285     hr = IDirectDraw4_GetSurfaceFromDC(dd4, NULL, (IDirectDrawSurface4 **)&tmp);
3286     ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3287     ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
3288
3289     IDirectDrawSurface4_Release(surf4);
3290     IDirectDrawSurface_Release(surf);
3291     IDirectDraw4_Release(dd4);
3292
3293     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3294     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3295
3296     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3297     ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
3298     dctest_surf((IDirectDrawSurface *) surf7, 2);
3299
3300     hr = IDirectDrawSurface7_GetDC(surf7, &dc);
3301     ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
3302
3303     hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, NULL);
3304     ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
3305
3306     hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
3307     ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
3308     ok(tmp7 == surf7, "Expected surface %p, got %p.\n\n", surf7, tmp7);
3309     IDirectDrawSurface7_Release(tmp7);
3310
3311     hr = IDirectDrawSurface7_ReleaseDC(surf7, dc);
3312     ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
3313
3314     dc = CreateCompatibleDC(NULL);
3315     ok(!!dc, "CreateCompatibleDC failed.\n");
3316
3317     tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
3318     hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
3319     ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3320     ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
3321
3322     ok(DeleteDC(dc), "DeleteDC failed.\n");
3323
3324     tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
3325     hr = IDirectDraw7_GetSurfaceFromDC(dd7, NULL, (IDirectDrawSurface7 **)&tmp7);
3326     ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3327     ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
3328
3329     IDirectDrawSurface7_Release(surf7);
3330     IDirectDraw7_Release(dd7);
3331 }
3332
3333 static void GetDCFormatTest(void)
3334 {
3335     DDSURFACEDESC2 ddsd;
3336     unsigned int i;
3337     IDirectDrawSurface7 *surface;
3338     IDirectDraw7 *dd7;
3339     HRESULT hr;
3340     HDC dc;
3341
3342     struct
3343     {
3344         const char *name;
3345         DDPIXELFORMAT fmt;
3346         BOOL getdc_capable;
3347         HRESULT alt_result;
3348     } testdata[] = {
3349         {
3350             "D3DFMT_A8R8G8B8",
3351             {
3352                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3353                 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
3354             },
3355             TRUE
3356         },
3357         {
3358             "D3DFMT_X8R8G8B8",
3359             {
3360                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3361                 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
3362             },
3363             TRUE
3364         },
3365         {
3366             "D3DFMT_X8B8G8R8",
3367             {
3368                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3369                 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
3370             },
3371             TRUE,
3372             DDERR_CANTCREATEDC /* Vista+ */
3373         },
3374         {
3375             "D3DFMT_X8B8G8R8",
3376             {
3377                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3378                        {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}
3379             },
3380             TRUE,
3381             DDERR_CANTCREATEDC /* Vista+ */
3382         },
3383         {
3384             "D3DFMT_A4R4G4B4",
3385             {
3386                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3387                        {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}
3388             },
3389             TRUE,
3390             DDERR_CANTCREATEDC /* Vista+ */
3391         },
3392         {
3393             "D3DFMT_X4R4G4B4",
3394             {
3395                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3396                        {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}
3397             },
3398             TRUE,
3399             DDERR_CANTCREATEDC /* Vista+ */
3400         },
3401         {
3402             "D3DFMT_R5G6B5",
3403             {
3404                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3405                        {16}, {0x0000F800}, {0x000007E0}, {0x0000001F}, {0x00000000}
3406             },
3407             TRUE
3408         },
3409         {
3410             "D3DFMT_A1R5G5B5",
3411             {
3412                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3413                        {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00008000}
3414             },
3415             TRUE
3416         },
3417         {
3418             "D3DFMT_X1R5G5B5",
3419             {
3420                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3421                        {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00000000}
3422             },
3423             TRUE
3424         },
3425         {
3426             "D3DFMT_R3G3B2",
3427             {
3428                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3429                        { 8}, {0x000000E0}, {0x0000001C}, {0x00000003}, {0x00000000}
3430             },
3431             FALSE
3432         },
3433         {
3434             /* Untested, windows test machine didn't support this format */
3435             "D3DFMT_A2R10G10B10",
3436             {
3437                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3438                        {32}, {0xC0000000}, {0x3FF00000}, {0x000FFC00}, {0x000003FF}
3439             },
3440             TRUE
3441         },
3442         /*
3443          * GetDC on a P8 surface fails unless the display mode is 8 bpp. This is not
3444          * implemented in wine yet, so disable the test for now. Succeeding P8 getDC
3445          * calls are tested in the ddraw.visual test.
3446          *
3447         {
3448             "D3DFMT_P8",
3449             {
3450                 sizeof(DDPIXELFORMAT), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0,
3451                 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3452             },
3453             FALSE
3454         },
3455          */
3456         {
3457             "D3DFMT_L8",
3458             {
3459                 sizeof(DDPIXELFORMAT), DDPF_LUMINANCE, 0,
3460                 {8 }, {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}
3461             },
3462             FALSE
3463         },
3464         {
3465             "D3DFMT_A8L8",
3466             {
3467                 sizeof(DDPIXELFORMAT), DDPF_ALPHAPIXELS | DDPF_LUMINANCE, 0,
3468                 {16}, {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}
3469             },
3470             FALSE
3471         },
3472         {
3473             "D3DFMT_DXT1",
3474             {
3475                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','1'),
3476                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3477             },
3478             FALSE
3479         },
3480         {
3481             "D3DFMT_DXT2",
3482             {
3483                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','2'),
3484                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3485             },
3486             FALSE
3487         },
3488         {
3489             "D3DFMT_DXT3",
3490             {
3491                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','3'),
3492                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3493             },
3494             FALSE
3495         },
3496         {
3497             "D3DFMT_DXT4",
3498             {
3499                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','4'),
3500                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3501             },
3502             FALSE
3503         },
3504         {
3505             "D3DFMT_DXT5",
3506             {
3507                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','5'),
3508                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3509             },
3510             FALSE
3511         },
3512     };
3513
3514     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3515     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed, hr = 0x%08x\n", hr);
3516
3517     for(i = 0; i < (sizeof(testdata) / sizeof(testdata[0])); i++)
3518     {
3519         memset(&ddsd, 0, sizeof(ddsd));
3520         ddsd.dwSize = sizeof(ddsd);
3521         ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3522         ddsd.dwWidth = 64;
3523         ddsd.dwHeight = 64;
3524         U4(ddsd).ddpfPixelFormat = testdata[i].fmt;
3525         ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3526
3527         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3528         if(FAILED(hr))
3529         {
3530             ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
3531             ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
3532             hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3533             if(FAILED(hr))
3534             {
3535                 skip("IDirectDraw7_CreateSurface failed, hr = 0x%08x, format %s\n", hr, testdata[i].name);
3536                 continue;
3537             }
3538         }
3539
3540         dc = (void *) 0x1234;
3541         hr = IDirectDrawSurface7_GetDC(surface, &dc);
3542         if(testdata[i].getdc_capable)
3543         {
3544             ok(SUCCEEDED(hr) ||
3545                (testdata[i].alt_result && hr == testdata[i].alt_result),
3546                "GetDC on a %s surface failed(0x%08x), expected it to work\n",
3547                testdata[i].name, hr);
3548         }
3549         else
3550         {
3551             ok(FAILED(hr), "GetDC on a %s surface succeeded(0x%08x), expected it to fail\n",
3552                testdata[i].name, hr);
3553         }
3554
3555         if(SUCCEEDED(hr))
3556         {
3557             IDirectDrawSurface7_ReleaseDC(surface, dc);
3558             ok(hr == DD_OK, "IDirectDrawSurface7_ReleaseDC failed, hr = 0x%08x\n", hr);
3559             dc = 0;
3560         }
3561         else
3562         {
3563             ok(dc == NULL, "After failed GetDC dc is %p\n", dc);
3564         }
3565
3566         IDirectDrawSurface7_Release(surface);
3567     }
3568
3569     IDirectDraw7_Release(dd7);
3570 }
3571
3572 static void BackBufferCreateSurfaceTest(void)
3573 {
3574     DDSURFACEDESC ddsd;
3575     DDSURFACEDESC created_ddsd;
3576     DDSURFACEDESC2 ddsd2;
3577     IDirectDrawSurface *surf;
3578     IDirectDrawSurface4 *surf4;
3579     IDirectDrawSurface7 *surf7;
3580     HRESULT hr;
3581     IDirectDraw2 *dd2;
3582     IDirectDraw4 *dd4;
3583     IDirectDraw7 *dd7;
3584
3585     const DWORD caps = DDSCAPS_BACKBUFFER;
3586     const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3587
3588     if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3589     {
3590         skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3591         return ;
3592     }
3593
3594     memset(&ddsd, 0, sizeof(ddsd));
3595     ddsd.dwSize = sizeof(ddsd);
3596     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3597     ddsd.dwWidth = 64;
3598     ddsd.dwHeight = 64;
3599     ddsd.ddsCaps.dwCaps = caps;
3600     memset(&ddsd2, 0, sizeof(ddsd2));
3601     ddsd2.dwSize = sizeof(ddsd2);
3602     ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3603     ddsd2.dwWidth = 64;
3604     ddsd2.dwHeight = 64;
3605     ddsd2.ddsCaps.dwCaps = caps;
3606     memset(&created_ddsd, 0, sizeof(created_ddsd));
3607     created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3608
3609     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
3610     ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3611     if (surf != NULL)
3612     {
3613         hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3614         ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3615         ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3616            "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3617            expected_caps);
3618         IDirectDrawSurface_Release(surf);
3619     }
3620
3621     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3622     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3623
3624     hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3625     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3626        DDERR_INVALIDCAPS, hr);
3627
3628     IDirectDraw2_Release(dd2);
3629
3630     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3631     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3632
3633     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3634     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3635        DDERR_INVALIDCAPS, hr);
3636
3637     IDirectDraw4_Release(dd4);
3638
3639     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3640     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3641
3642     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3643     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3644        DDERR_INVALIDCAPS, hr);
3645
3646     IDirectDraw7_Release(dd7);
3647 }
3648
3649 static void BackBufferAttachmentFlipTest(void)
3650 {
3651     HRESULT hr;
3652     IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3653     DDSURFACEDESC ddsd;
3654     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3655
3656     hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3657     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3658
3659     /* Perform attachment tests on a back-buffer */
3660     memset(&ddsd, 0, sizeof(ddsd));
3661     ddsd.dwSize = sizeof(ddsd);
3662     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3663     ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3664     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3665     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3666     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
3667     ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3668
3669     if (surface2 != NULL)
3670     {
3671         /* Try a single primary and a two back buffers */
3672         memset(&ddsd, 0, sizeof(ddsd));
3673         ddsd.dwSize = sizeof(ddsd);
3674         ddsd.dwFlags = DDSD_CAPS;
3675         ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3676         hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
3677         ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3678
3679         memset(&ddsd, 0, sizeof(ddsd));
3680         ddsd.dwSize = sizeof(ddsd);
3681         ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3682         ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3683         ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3684         ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3685         hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
3686         ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3687
3688         /* This one has a different size */
3689         memset(&ddsd, 0, sizeof(ddsd));
3690         ddsd.dwSize = sizeof(ddsd);
3691         ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3692         ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3693         ddsd.dwWidth = 128;
3694         ddsd.dwHeight = 128;
3695         hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
3696         ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3697
3698         hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3699         todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3700            "Attaching a back buffer to a front buffer returned %08x\n", hr);
3701         if(SUCCEEDED(hr))
3702         {
3703             /* Try flipping the surfaces */
3704             hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3705             todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3706             hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3707             todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3708
3709             /* Try the reverse without detaching first */
3710             hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3711             ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3712             hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3713             ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3714         }
3715         hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3716         todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3717            "Attaching a front buffer to a back buffer returned %08x\n", hr);
3718         if(SUCCEEDED(hr))
3719         {
3720             /* Try flipping the surfaces */
3721             hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3722             todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3723             hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3724             todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3725
3726             /* Try to detach reversed */
3727             hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3728             ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3729             /* Now the proper detach */
3730             hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3731             ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3732         }
3733         hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3734         todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3735            "Attaching a back buffer to another back buffer returned %08x\n", hr);
3736         if(SUCCEEDED(hr))
3737         {
3738             /* Try flipping the surfaces */
3739             hr = IDirectDrawSurface_Flip(surface3, NULL, DDFLIP_WAIT);
3740             todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3741             hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3742             todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3743             hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3744             ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3745
3746             hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3747             ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3748         }
3749         hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3750         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3751         hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3752         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3753
3754         IDirectDrawSurface_Release(surface4);
3755         IDirectDrawSurface_Release(surface3);
3756         IDirectDrawSurface_Release(surface2);
3757         IDirectDrawSurface_Release(surface1);
3758     }
3759
3760     hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
3761     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3762
3763     DestroyWindow(window);
3764 }
3765
3766 static void CreateSurfaceBadCapsSizeTest(void)
3767 {
3768     DDSURFACEDESC ddsd_ok;
3769     DDSURFACEDESC ddsd_bad1;
3770     DDSURFACEDESC ddsd_bad2;
3771     DDSURFACEDESC ddsd_bad3;
3772     DDSURFACEDESC ddsd_bad4;
3773     DDSURFACEDESC2 ddsd2_ok;
3774     DDSURFACEDESC2 ddsd2_bad1;
3775     DDSURFACEDESC2 ddsd2_bad2;
3776     DDSURFACEDESC2 ddsd2_bad3;
3777     DDSURFACEDESC2 ddsd2_bad4;
3778     IDirectDrawSurface *surf;
3779     IDirectDrawSurface4 *surf4;
3780     IDirectDrawSurface7 *surf7;
3781     HRESULT hr;
3782     IDirectDraw2 *dd2;
3783     IDirectDraw4 *dd4;
3784     IDirectDraw7 *dd7;
3785
3786     const DWORD caps = DDSCAPS_OFFSCREENPLAIN;
3787
3788     memset(&ddsd_ok, 0, sizeof(ddsd_ok));
3789     ddsd_ok.dwSize = sizeof(ddsd_ok);
3790     ddsd_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3791     ddsd_ok.dwWidth = 64;
3792     ddsd_ok.dwHeight = 64;
3793     ddsd_ok.ddsCaps.dwCaps = caps;
3794     memcpy(&ddsd_bad1, &ddsd_ok, sizeof(ddsd_bad1));
3795     ddsd_bad1.dwSize--;
3796     memcpy(&ddsd_bad2, &ddsd_ok, sizeof(ddsd_bad2));
3797     ddsd_bad2.dwSize++;
3798     memcpy(&ddsd_bad3, &ddsd_ok, sizeof(ddsd_bad3));
3799     ddsd_bad3.dwSize = 0;
3800     memcpy(&ddsd_bad4, &ddsd_ok, sizeof(ddsd_bad4));
3801     ddsd_bad4.dwSize = sizeof(DDSURFACEDESC2);
3802
3803     memset(&ddsd2_ok, 0, sizeof(ddsd2_ok));
3804     ddsd2_ok.dwSize = sizeof(ddsd2_ok);
3805     ddsd2_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3806     ddsd2_ok.dwWidth = 64;
3807     ddsd2_ok.dwHeight = 64;
3808     ddsd2_ok.ddsCaps.dwCaps = caps;
3809     memcpy(&ddsd2_bad1, &ddsd2_ok, sizeof(ddsd2_bad1));
3810     ddsd2_bad1.dwSize--;
3811     memcpy(&ddsd2_bad2, &ddsd2_ok, sizeof(ddsd2_bad2));
3812     ddsd2_bad2.dwSize++;
3813     memcpy(&ddsd2_bad3, &ddsd2_ok, sizeof(ddsd2_bad3));
3814     ddsd2_bad3.dwSize = 0;
3815     memcpy(&ddsd2_bad4, &ddsd2_ok, sizeof(ddsd2_bad4));
3816     ddsd2_bad4.dwSize = sizeof(DDSURFACEDESC);
3817
3818     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_ok, &surf, NULL);
3819     ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3820     IDirectDrawSurface_Release(surf);
3821
3822     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad1, &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, &ddsd_bad2, &surf, NULL);
3826     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3827        DDERR_INVALIDPARAMS, hr);
3828     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad3, &surf, NULL);
3829     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3830        DDERR_INVALIDPARAMS, hr);
3831     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad4, &surf, NULL);
3832     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3833        DDERR_INVALIDPARAMS, hr);
3834     hr = IDirectDraw_CreateSurface(lpDD, NULL, &surf, NULL);
3835     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3836        DDERR_INVALIDPARAMS, hr);
3837
3838     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3839     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3840
3841     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_ok, &surf, NULL);
3842     ok(SUCCEEDED(hr), "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
3843     IDirectDrawSurface_Release(surf);
3844
3845     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad1, &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, &ddsd_bad2, &surf, NULL);
3849     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3850        DDERR_INVALIDPARAMS, hr);
3851     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad3, &surf, NULL);
3852     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3853        DDERR_INVALIDPARAMS, hr);
3854     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad4, &surf, NULL);
3855     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3856        DDERR_INVALIDPARAMS, hr);
3857     hr = IDirectDraw2_CreateSurface(dd2, NULL, &surf, NULL);
3858     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3859        DDERR_INVALIDPARAMS, hr);
3860
3861     IDirectDraw2_Release(dd2);
3862
3863     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3864     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3865
3866     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_ok, &surf4, NULL);
3867     ok(SUCCEEDED(hr), "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
3868     IDirectDrawSurface4_Release(surf4);
3869
3870     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad1, &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, &ddsd2_bad2, &surf4, NULL);
3874     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3875        DDERR_INVALIDPARAMS, hr);
3876     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad3, &surf4, NULL);
3877     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3878        DDERR_INVALIDPARAMS, hr);
3879     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad4, &surf4, NULL);
3880     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3881        DDERR_INVALIDPARAMS, hr);
3882     hr = IDirectDraw4_CreateSurface(dd4, NULL, &surf4, NULL);
3883     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3884        DDERR_INVALIDPARAMS, hr);
3885
3886     IDirectDraw4_Release(dd4);
3887
3888     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3889     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3890
3891     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_ok, &surf7, NULL);
3892     ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
3893     IDirectDrawSurface7_Release(surf7);
3894
3895     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad1, &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, &ddsd2_bad2, &surf7, NULL);
3899     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3900        DDERR_INVALIDPARAMS, hr);
3901     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad3, &surf7, NULL);
3902     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3903        DDERR_INVALIDPARAMS, hr);
3904     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad4, &surf7, NULL);
3905     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3906        DDERR_INVALIDPARAMS, hr);
3907     hr = IDirectDraw7_CreateSurface(dd7, NULL, &surf7, NULL);
3908     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3909        DDERR_INVALIDPARAMS, hr);
3910
3911     IDirectDraw7_Release(dd7);
3912 }
3913
3914 static void reset_ddsd(DDSURFACEDESC *ddsd)
3915 {
3916     memset(ddsd, 0, sizeof(*ddsd));
3917     ddsd->dwSize = sizeof(*ddsd);
3918 }
3919
3920 static void no_ddsd_caps_test(void)
3921 {
3922     DDSURFACEDESC ddsd;
3923     HRESULT hr;
3924     IDirectDrawSurface *surface;
3925
3926     reset_ddsd(&ddsd);
3927     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
3928     ddsd.dwWidth = 128;
3929     ddsd.dwHeight = 128;
3930     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3931     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3932     ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
3933     reset_ddsd(&ddsd);
3934     hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
3935     IDirectDrawSurface_Release(surface);
3936     ok(ddsd.dwFlags & DDSD_CAPS, "DDSD_CAPS is not set\n");
3937     ok(ddsd.ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN, "DDSCAPS_OFFSCREENPLAIN is not set\n");
3938
3939     reset_ddsd(&ddsd);
3940     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3941     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3942     ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
3943     reset_ddsd(&ddsd);
3944     hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
3945     IDirectDrawSurface_Release(surface);
3946     ok(ddsd.dwFlags & DDSD_CAPS, "DDSD_CAPS is not set\n");
3947     ok(ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE, "DDSCAPS_OFFSCREENPLAIN is not set\n");
3948
3949     reset_ddsd(&ddsd);
3950     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
3951     ddsd.dwWidth = 128;
3952     ddsd.dwHeight = 128;
3953     ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
3954     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3955     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw_CreateSurface returned %#x, expected DDERR_INVALIDCAPS.\n", hr);
3956 }
3957
3958 static void dump_format(const DDPIXELFORMAT *fmt)
3959 {
3960     trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %u\n", fmt->dwFlags, fmt->dwFourCC,
3961           U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
3962     trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
3963           U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
3964 }
3965
3966 static void zbufferbitdepth_test(void)
3967 {
3968     enum zfmt_succeed
3969     {
3970         ZFMT_SUPPORTED_ALWAYS,
3971         ZFMT_SUPPORTED_NEVER,
3972         ZFMT_SUPPORTED_HWDEPENDENT
3973     };
3974     struct
3975     {
3976         DWORD depth;
3977         enum zfmt_succeed supported;
3978         DDPIXELFORMAT pf;
3979     }
3980     test_data[] =
3981     {
3982         {
3983             16, ZFMT_SUPPORTED_ALWAYS,
3984             {
3985                 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3986                 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
3987             }
3988         },
3989         {
3990             24, ZFMT_SUPPORTED_HWDEPENDENT,
3991             {
3992                 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
3993                 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
3994             }
3995         },
3996         {
3997             32, ZFMT_SUPPORTED_HWDEPENDENT,
3998             {
3999                 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
4000                 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
4001             }
4002         },
4003         /* Returns DDERR_INVALIDPARAMS instead of DDERR_INVALIDPIXELFORMAT.
4004          * Disabled for now
4005         {
4006             0, ZFMT_SUPPORTED_NEVER
4007         },
4008         */
4009         {
4010             15, ZFMT_SUPPORTED_NEVER
4011         },
4012         {
4013             28, ZFMT_SUPPORTED_NEVER
4014         },
4015         {
4016             40, ZFMT_SUPPORTED_NEVER
4017         },
4018     };
4019
4020     DDSURFACEDESC ddsd;
4021     IDirectDrawSurface *surface;
4022     HRESULT hr;
4023     unsigned int i;
4024     DDCAPS caps;
4025
4026     memset(&caps, 0, sizeof(caps));
4027     caps.dwSize = sizeof(caps);
4028     hr = IDirectDraw_GetCaps(lpDD, &caps, NULL);
4029     ok(SUCCEEDED(hr), "IDirectDraw_GetCaps failed, hr %#x.\n", hr);
4030     if (!(caps.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
4031     {
4032         skip("Z buffers not supported, skipping DDSD_ZBUFFERBITDEPTH test\n");
4033         return;
4034     }
4035
4036     for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
4037     {
4038         reset_ddsd(&ddsd);
4039         ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH;
4040         ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4041         ddsd.dwWidth = 256;
4042         ddsd.dwHeight = 256;
4043         U2(ddsd).dwZBufferBitDepth = test_data[i].depth;
4044
4045         hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
4046         if (test_data[i].supported == ZFMT_SUPPORTED_ALWAYS)
4047         {
4048             ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
4049         }
4050         else if (test_data[i].supported == ZFMT_SUPPORTED_NEVER)
4051         {
4052             ok(hr == DDERR_INVALIDPIXELFORMAT, "IDirectDraw_CreateSurface returned %#x, expected %x.\n",
4053                hr, DDERR_INVALIDPIXELFORMAT);
4054         }
4055         if (!surface) continue;
4056
4057         reset_ddsd(&ddsd);
4058         hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
4059         ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
4060         IDirectDrawSurface_Release(surface);
4061
4062         ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
4063         ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
4064         /* Yet the ddpfPixelFormat member contains valid data */
4065         if (memcmp(&ddsd.ddpfPixelFormat, &test_data[i].pf, ddsd.ddpfPixelFormat.dwSize))
4066         {
4067             ok(0, "Unexpected format for depth %u\n", test_data[i].depth);
4068             dump_format(&ddsd.ddpfPixelFormat);
4069         }
4070     }
4071
4072     /* DDSD_ZBUFFERBITDEPTH vs DDSD_PIXELFORMAT? */
4073     reset_ddsd(&ddsd);
4074     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_ZBUFFERBITDEPTH;
4075     ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4076     ddsd.dwWidth = 256;
4077     ddsd.dwHeight = 256;
4078     U2(ddsd).dwZBufferBitDepth = 24;
4079     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
4080     ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
4081     U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth = 16;
4082     U3(ddsd.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
4083
4084     surface = NULL;
4085     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
4086     ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
4087     if (!surface) return;
4088     reset_ddsd(&ddsd);
4089     hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
4090     ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
4091     IDirectDrawSurface_Release(surface);
4092     ok(U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth == 16, "Expected a 16bpp depth buffer, got %ubpp\n",
4093        U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth);
4094     ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
4095     ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
4096     ok(U2(ddsd).dwZBufferBitDepth == 16, "Expected dwZBufferBitDepth=16, got %u\n",
4097        U2(ddsd).dwZBufferBitDepth);
4098
4099     /* DDSD_PIXELFORMAT vs invalid ZBUFFERBITDEPTH */
4100     reset_ddsd(&ddsd);
4101     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_PIXELFORMAT;
4102     ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4103     ddsd.dwWidth = 256;
4104     ddsd.dwHeight = 256;
4105     U2(ddsd).dwZBufferBitDepth = 40;
4106     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
4107     ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
4108     U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth = 16;
4109     U3(ddsd.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
4110     surface = NULL;
4111     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
4112     ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
4113     if (surface) IDirectDrawSurface_Release(surface);
4114
4115     /* Create a PIXELFORMAT-only surface, see if ZBUFFERBITDEPTH is set */
4116     reset_ddsd(&ddsd);
4117     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
4118     ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4119     ddsd.dwWidth = 256;
4120     ddsd.dwHeight = 256;
4121     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
4122     ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
4123     U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth = 16;
4124     U3(ddsd.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
4125     surface = NULL;
4126     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
4127     ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
4128     reset_ddsd(&ddsd);
4129     hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
4130     ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
4131     IDirectDrawSurface_Release(surface);
4132     ok(U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth == 16, "Expected a 16bpp depth buffer, got %ubpp\n",
4133        U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth);
4134     ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
4135     ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
4136     ok(U2(ddsd).dwZBufferBitDepth == 16, "Expected dwZBufferBitDepth=16, got %u\n",
4137        U2(ddsd).dwZBufferBitDepth);
4138 }
4139
4140 static void test_ddsd(DDSURFACEDESC *ddsd, BOOL expect_pf, BOOL expect_zd, const char *name, DWORD z_bit_depth)
4141 {
4142     IDirectDrawSurface *surface;
4143     IDirectDrawSurface7 *surface7;
4144     HRESULT hr;
4145     DDSURFACEDESC out;
4146     DDSURFACEDESC2 out2;
4147
4148     hr = IDirectDraw_CreateSurface(lpDD, ddsd, &surface, NULL);
4149     if (hr == DDERR_NOZBUFFERHW)
4150     {
4151         skip("Z buffers not supported, skipping Z flag test\n");
4152         return;
4153     }
4154     ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
4155     hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **) &surface7);
4156     ok(SUCCEEDED(hr), "IDirectDrawSurface_QueryInterface failed, hr %#x.\n", hr);
4157
4158     reset_ddsd(&out);
4159     hr = IDirectDrawSurface_GetSurfaceDesc(surface, &out);
4160     ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
4161     memset(&out2, 0, sizeof(out2));
4162     out2.dwSize = sizeof(out2);
4163     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &out2);
4164     ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
4165
4166     if (expect_pf)
4167     {
4168         ok(out.dwFlags & DDSD_PIXELFORMAT, "%s surface: Expected DDSD_PIXELFORMAT to be set\n", name);
4169         ok(out2.dwFlags & DDSD_PIXELFORMAT,
4170                 "%s surface: Expected DDSD_PIXELFORMAT to be set in DDSURFACEDESC2\n", name);
4171     }
4172     else
4173     {
4174         ok(!(out.dwFlags & DDSD_PIXELFORMAT), "%s surface: Expected DDSD_PIXELFORMAT not to be set\n", name);
4175         ok(out2.dwFlags & DDSD_PIXELFORMAT,
4176                 "%s surface: Expected DDSD_PIXELFORMAT to be set in DDSURFACEDESC2\n", name);
4177     }
4178     if (expect_zd)
4179     {
4180         ok(out.dwFlags & DDSD_ZBUFFERBITDEPTH, "%s surface: Expected DDSD_ZBUFFERBITDEPTH to be set\n", name);
4181         ok(U2(out).dwZBufferBitDepth == z_bit_depth, "ZBufferBitDepth is %u, expected %u\n",
4182                 U2(out).dwZBufferBitDepth, z_bit_depth);
4183         ok(!(out2.dwFlags & DDSD_ZBUFFERBITDEPTH),
4184                 "%s surface: Did not expect DDSD_ZBUFFERBITDEPTH to be set in DDSURFACEDESC2\n", name);
4185         /* dwMipMapCount and dwZBufferBitDepth share the same union */
4186         ok(U2(out2).dwMipMapCount == 0, "dwMipMapCount is %u, expected 0\n", U2(out2).dwMipMapCount);
4187     }
4188     else
4189     {
4190         ok(!(out.dwFlags & DDSD_ZBUFFERBITDEPTH), "%s surface: Expected DDSD_ZBUFFERBITDEPTH not to be set\n", name);
4191         ok(U2(out).dwZBufferBitDepth == 0, "ZBufferBitDepth is %u, expected 0\n", U2(out).dwZBufferBitDepth);
4192         ok(!(out2.dwFlags & DDSD_ZBUFFERBITDEPTH),
4193                 "%s surface: Did not expect DDSD_ZBUFFERBITDEPTH to be set in DDSURFACEDESC2\n", name);
4194         ok(U2(out2).dwMipMapCount == 0, "dwMipMapCount is %u, expected 0\n", U2(out2).dwMipMapCount);
4195     }
4196
4197     reset_ddsd(&out);
4198     hr = IDirectDrawSurface_Lock(surface, NULL, &out, 0, NULL);
4199     if (SUCCEEDED(hr))
4200     {
4201         hr = IDirectDrawSurface_Unlock(surface, NULL);
4202         ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
4203
4204         /* DDSD_ZBUFFERBITDEPTH is never set on Nvidia, but follows GetSurfaceDesc rules on AMD */
4205         if (!expect_zd)
4206         {
4207             ok(!(out.dwFlags & DDSD_ZBUFFERBITDEPTH),
4208                 "Lock %s surface: Expected DDSD_ZBUFFERBITDEPTH not to be set\n", name);
4209         }
4210
4211         /* DDSD_PIXELFORMAT follows GetSurfaceDesc rules */
4212         if (expect_pf)
4213         {
4214             ok(out.dwFlags & DDSD_PIXELFORMAT, "%s surface: Expected DDSD_PIXELFORMAT to be set\n", name);
4215         }
4216         else
4217         {
4218             ok(!(out.dwFlags & DDSD_PIXELFORMAT),
4219                 "Lock %s surface: Expected DDSD_PIXELFORMAT not to be set\n", name);
4220         }
4221         if (out.dwFlags & DDSD_ZBUFFERBITDEPTH)
4222             ok(U2(out).dwZBufferBitDepth == z_bit_depth, "ZBufferBitDepth is %u, expected %u\n",
4223                     U2(out).dwZBufferBitDepth, z_bit_depth);
4224         else
4225             ok(U2(out).dwZBufferBitDepth == 0, "ZBufferBitDepth is %u, expected 0\n", U2(out).dwZBufferBitDepth);
4226     }
4227
4228     hr = IDirectDrawSurface7_Lock(surface7, NULL, &out2, 0, NULL);
4229     ok(SUCCEEDED(hr), "IDirectDrawSurface7_Lock failed, hr %#x.\n", hr);
4230     if (SUCCEEDED(hr))
4231     {
4232         hr = IDirectDrawSurface7_Unlock(surface7, NULL);
4233         ok(SUCCEEDED(hr), "IDirectDrawSurface7_Unlock failed, hr %#x.\n", hr);
4234         /* DDSD_PIXELFORMAT is always set, DDSD_ZBUFFERBITDEPTH never */
4235         ok(out2.dwFlags & DDSD_PIXELFORMAT,
4236                 "Lock %s surface: Expected DDSD_PIXELFORMAT to be set in DDSURFACEDESC2\n", name);
4237         ok(!(out2.dwFlags & DDSD_ZBUFFERBITDEPTH),
4238                 "Lock %s surface: Did not expect DDSD_ZBUFFERBITDEPTH to be set in DDSURFACEDESC2\n", name);
4239         ok(U2(out2).dwMipMapCount == 0, "dwMipMapCount is %u, expected 0\n", U2(out2).dwMipMapCount);
4240     }
4241
4242     IDirectDrawSurface7_Release(surface7);
4243     IDirectDrawSurface_Release(surface);
4244 }
4245
4246 static void pixelformat_flag_test(void)
4247 {
4248     DDSURFACEDESC ddsd;
4249     DDCAPS caps;
4250     HRESULT hr;
4251
4252     memset(&caps, 0, sizeof(caps));
4253     caps.dwSize = sizeof(caps);
4254     hr = IDirectDraw_GetCaps(lpDD, &caps, NULL);
4255     ok(SUCCEEDED(hr), "IDirectDraw_GetCaps failed, hr %#x.\n", hr);
4256     if (!(caps.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
4257     {
4258         skip("Z buffers not supported, skipping DDSD_PIXELFORMAT test\n");
4259         return;
4260     }
4261
4262     reset_ddsd(&ddsd);
4263     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
4264     ddsd.dwWidth = 64;
4265     ddsd.dwHeight = 64;
4266     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
4267     test_ddsd(&ddsd, TRUE, FALSE, "offscreen plain", ~0U);
4268
4269     reset_ddsd(&ddsd);
4270     ddsd.dwFlags = DDSD_CAPS;
4271     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
4272     test_ddsd(&ddsd, TRUE, FALSE, "primary", ~0U);
4273
4274     reset_ddsd(&ddsd);
4275     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_ZBUFFERBITDEPTH;
4276     ddsd.dwWidth = 64;
4277     ddsd.dwHeight = 64;
4278     U2(ddsd).dwZBufferBitDepth = 16;
4279     ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
4280     test_ddsd(&ddsd, FALSE, TRUE, "Z buffer", 16);
4281 }
4282
4283 static void set_surface_desc_test(void)
4284 {
4285     HRESULT hr;
4286     DDSURFACEDESC ddsd;
4287     IDirectDrawSurface *surface;
4288     IDirectDrawSurface3 *surface3;
4289     BYTE data[8*8*4];
4290
4291     hr = IDirectDraw_CreateSurface(lpDD, NULL, &surface, NULL);
4292     ok(hr == DDERR_INVALIDPARAMS, "CreateSurface with a NULL DDSD returned %#x,"
4293             " expected DDERR_INVALIDPARAMS(%#x)\n", hr, DDERR_INVALIDPARAMS);
4294
4295     reset_ddsd(&ddsd);
4296     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
4297     ddsd.dwWidth = 8;
4298     ddsd.dwHeight = 8;
4299     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
4300     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4301     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
4302     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000;
4303     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00;
4304     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff;
4305     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
4306
4307     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
4308     ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
4309
4310     hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface3, (void **) &surface3);
4311     ok(SUCCEEDED(hr), "IDirectDrawSurface_QueryInterface failed, hr %#x.\n", hr);
4312     IDirectDrawSurface_Release(surface);
4313
4314     reset_ddsd(&ddsd);
4315     ddsd.dwFlags = DDSD_LPSURFACE;
4316     ddsd.lpSurface = data;
4317     hr = IDirectDrawSurface3_SetSurfaceDesc(surface3, &ddsd, 0);
4318     ok(SUCCEEDED(hr), "IDirectDrawSurface3_SetSurfaceDesc failed, hr %#x.\n", hr);
4319
4320     /* Redundantly setting the same lpSurface is not an error */
4321     hr = IDirectDrawSurface3_SetSurfaceDesc(surface3, &ddsd, 0);
4322     ok(SUCCEEDED(hr), "IDirectDrawSurface3_SetSurfaceDesc failed, hr %#x.\n", hr);
4323
4324     hr = IDirectDrawSurface3_SetSurfaceDesc(surface3, &ddsd, 1);
4325     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface3_SetSurfaceDesc returned %#x, expected"
4326             " DDERR_INVALIDPARAMS(%#x)\n", hr, DDERR_INVALIDPARAMS);
4327
4328     hr = IDirectDrawSurface3_SetSurfaceDesc(surface3, NULL, 0);
4329     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface3_SetSurfaceDesc returned %#x, expected"
4330             " DDERR_INVALIDPARAMS(%#x)\n", hr, DDERR_INVALIDPARAMS);
4331
4332     IDirectDrawSurface_Release(surface3);
4333 }
4334
4335 START_TEST(dsurface)
4336 {
4337     HRESULT ret;
4338     IDirectDraw4 *dd4;
4339
4340     if (!CreateDirectDraw())
4341         return;
4342
4343     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
4344     if (ret == E_NOINTERFACE)
4345     {
4346         win_skip("DirectDraw4 and higher are not supported\n");
4347         ReleaseDirectDraw();
4348         return;
4349     }
4350     IDirectDraw_Release(dd4);
4351
4352     if(!can_create_primary_surface())
4353     {
4354         skip("Unable to create primary surface\n");
4355         return;
4356     }
4357
4358     ddcaps.dwSize = sizeof(DDCAPS);
4359     ret = IDirectDraw_GetCaps(lpDD, &ddcaps, NULL);
4360     if (ret != DD_OK)
4361     {
4362         skip("IDirectDraw_GetCaps failed with %08x\n", ret);
4363         return;
4364     }
4365
4366     MipMapCreationTest();
4367     SrcColorKey32BlitTest();
4368     QueryInterface();
4369     GetDDInterface_1();
4370     GetDDInterface_2();
4371     GetDDInterface_4();
4372     GetDDInterface_7();
4373     IFaceRefCount();
4374     EnumTest();
4375     AttachmentTest();
4376     AttachmentTest7();
4377     CubeMapTest();
4378     test_lockrect_invalid();
4379     CompressedTest();
4380     SizeTest();
4381     PrivateDataTest();
4382     BltParamTest();
4383     StructSizeTest();
4384     PaletteTest();
4385     SurfaceCapsTest();
4386     GetDCTest();
4387     GetDCFormatTest();
4388     BackBufferCreateSurfaceTest();
4389     BackBufferAttachmentFlipTest();
4390     CreateSurfaceBadCapsSizeTest();
4391     no_ddsd_caps_test();
4392     zbufferbitdepth_test();
4393     pixelformat_flag_test();
4394     set_surface_desc_test();
4395     ReleaseDirectDraw();
4396 }