mcicda: Exclude unused headers.
[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  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 #define COBJMACROS
24
25 #include <assert.h>
26 #include "wine/test.h"
27 #include "ddraw.h"
28 #include "unknwn.h"
29
30 static LPDIRECTDRAW lpDD = NULL;
31
32 static BOOL CreateDirectDraw(void)
33 {
34     HRESULT rc;
35
36     rc = DirectDrawCreate(NULL, &lpDD, NULL);
37     ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
38     if (!lpDD) {
39         trace("DirectDrawCreateEx() failed with an error %x\n", rc);
40         return FALSE;
41     }
42
43     rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
44     ok(rc==DD_OK,"SetCooperativeLevel returned: %x\n",rc);
45
46     return TRUE;
47 }
48
49
50 static void ReleaseDirectDraw(void)
51 {
52     if( lpDD != NULL )
53     {
54         IDirectDraw_Release(lpDD);
55         lpDD = NULL;
56     }
57 }
58
59 static void MipMapCreationTest(void)
60 {
61     LPDIRECTDRAWSURFACE lpDDSMipMapTest;
62     DDSURFACEDESC ddsd;
63     HRESULT rc;
64
65     /* First mipmap creation test: create a surface with DDSCAPS_COMPLEX,
66        DDSCAPS_MIPMAP, and DDSD_MIPMAPCOUNT. This create the number of
67         requested mipmap levels. */
68     ddsd.dwSize = sizeof(ddsd);
69     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
70     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
71     U2(ddsd).dwMipMapCount = 3;
72     ddsd.dwWidth = 128;
73     ddsd.dwHeight = 32;
74     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
75     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
76
77     /* Check the number of created mipmaps */
78     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
79     ddsd.dwSize = sizeof(ddsd);
80     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
81     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
82     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
83         "GetSurfaceDesc returned no mipmapcount.\n");
84     ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %d.\n",
85         U2(ddsd).dwMipMapCount);
86
87     /* Destroy the surface. */
88     IDirectDrawSurface_Release(lpDDSMipMapTest);
89
90
91     /* Second mipmap creation test: create a surface without a mipmap
92        count, with DDSCAPS_MIPMAP and without DDSCAPS_COMPLEX.
93        This creates a single mipmap level. */
94     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
95     ddsd.dwSize = sizeof(ddsd);
96     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
97     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
98     ddsd.dwWidth = 128;
99     ddsd.dwHeight = 32;
100     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
101     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
102
103     /* Check the number of created mipmaps */
104     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
105     ddsd.dwSize = sizeof(ddsd);
106     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
107     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
108     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
109         "GetSurfaceDesc returned no mipmapcount.\n");
110     ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %d.\n",
111         U2(ddsd).dwMipMapCount);
112
113     /* Destroy the surface. */
114     IDirectDrawSurface_Release(lpDDSMipMapTest);
115
116
117     /* Third mipmap creation test: create a surface with DDSCAPS_MIPMAP,
118         DDSCAPS_COMPLEX and without DDSD_MIPMAPCOUNT.
119        It's an undocumented features where a chain of mipmaps, starting from
120        he specified size and down to the smallest size, is automatically
121        created.
122        Anarchy Online needs this feature to work. */
123     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
124     ddsd.dwSize = sizeof(ddsd);
125     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
126     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
127     ddsd.dwWidth = 128;
128     ddsd.dwHeight = 32;
129     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
130     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
131
132     /* Check the number of created mipmaps */
133     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
134     ddsd.dwSize = sizeof(ddsd);
135     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
136     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
137     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
138         "GetSurfaceDesc returned no mipmapcount.\n");
139     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
140         U2(ddsd).dwMipMapCount);
141
142     /* Destroy the surface. */
143     IDirectDrawSurface_Release(lpDDSMipMapTest);
144
145
146     /* Fourth mipmap creation test: same as above with a different texture
147        size.
148        The purpose is to verify that the number of generated mipmaps is
149        dependent on the smallest dimension. */
150     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
151     ddsd.dwSize = sizeof(ddsd);
152     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
153     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
154     ddsd.dwWidth = 32;
155     ddsd.dwHeight = 64;
156     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
157     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
158
159     /* Check the number of created mipmaps */
160     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
161     ddsd.dwSize = sizeof(ddsd);
162     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
163     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
164     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
165         "GetSurfaceDesc returned no mipmapcount.\n");
166     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
167         U2(ddsd).dwMipMapCount);
168
169     /* Destroy the surface. */
170     IDirectDrawSurface_Release(lpDDSMipMapTest);
171 }
172
173 static void SrcColorKey32BlitTest(void)
174 {
175     LPDIRECTDRAWSURFACE lpSrc;
176     LPDIRECTDRAWSURFACE lpDst;
177     DDSURFACEDESC ddsd;
178     DDSURFACEDESC ddsd2;
179     DDCOLORKEY DDColorKey;
180     LPDWORD lpData;
181     HRESULT rc;
182     DDBLTFX fx;
183
184     ddsd2.dwSize = sizeof(ddsd2);
185     ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
186
187     ddsd.dwSize = sizeof(ddsd);
188     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
189     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
190     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
191     ddsd.dwWidth = 800;
192     ddsd.dwHeight = 600;
193     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
194     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
195     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
196     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
197     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
198     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
199     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
200
201     ddsd.dwFlags |= DDSD_CKSRCBLT;
202     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
203     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
204     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
205     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
206
207     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
208     ok(rc==DD_OK,"Lock returned: %x\n",rc);
209     lpData = (LPDWORD)ddsd2.lpSurface;
210     lpData[0] = 0xCCCCCCCC;
211     lpData[1] = 0xCCCCCCCC;
212     lpData[2] = 0xCCCCCCCC;
213     lpData[3] = 0xCCCCCCCC;
214     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
215     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
216
217     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
218     ok(rc==DD_OK,"Lock returned: %x\n",rc);
219     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
220     lpData = (LPDWORD)ddsd2.lpSurface;
221     lpData[0] = 0x77010203;
222     lpData[1] = 0x00010203;
223     lpData[2] = 0x77FF00FF;
224     lpData[3] = 0x00FF00FF;
225     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
226     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
227
228     IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
229
230     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
231     ok(rc==DD_OK,"Lock returned: %x\n",rc);
232     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
233     lpData = (LPDWORD)ddsd2.lpSurface;
234     ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
235        "Destination data after blitting is not correct\n");
236     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
237     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
238
239     /* Also test SetColorKey */
240     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
241     ok(DDColorKey.dwColorSpaceLowValue == 0xFF00FF && DDColorKey.dwColorSpaceHighValue == 0xFF00FF,
242        "GetColorKey does not return the colorkey used at surface creation\n");
243
244     DDColorKey.dwColorSpaceLowValue = 0x00FF00;
245     DDColorKey.dwColorSpaceHighValue = 0x00FF00;
246     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
247
248     DDColorKey.dwColorSpaceLowValue = 0;
249     DDColorKey.dwColorSpaceHighValue = 0;
250     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
251     ok(DDColorKey.dwColorSpaceLowValue == 0x00FF00 && DDColorKey.dwColorSpaceHighValue == 0x00FF00,
252        "GetColorKey does not return the colorkey set with SetColorKey\n");
253
254     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
255     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
256     IDirectDrawSurface_GetSurfaceDesc(lpSrc, &ddsd);
257     ok(ddsd.ddckCKSrcBlt.dwColorSpaceLowValue == 0x00FF00 && ddsd.ddckCKSrcBlt.dwColorSpaceHighValue == 0x00FF00,
258        "GetSurfaceDesc does not return the colorkey set with SetColorKey\n");
259
260     IDirectDrawSurface_Release(lpSrc);
261     IDirectDrawSurface_Release(lpDst);
262
263     /* start with a new set of surfaces to test the color keying parameters to blit */
264     memset(&ddsd, 0, sizeof(ddsd));
265     ddsd.dwSize = sizeof(ddsd);
266     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
267     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
268     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
269     ddsd.dwWidth = 800;
270     ddsd.dwHeight = 600;
271     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
272     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
273     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
274     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
275     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
276     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0xFF0000;
277     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0xFF0000;
278     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x00FF00;
279     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x00FF00;
280     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
281     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
282     if(FAILED(rc))
283     {
284         skip("Failed to create surface\n");
285         return;
286     }
287
288     /* start with a new set of surfaces to test the color keying parameters to blit */
289     memset(&ddsd, 0, sizeof(ddsd));
290     ddsd.dwSize = sizeof(ddsd);
291     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
292     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
293     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
294     ddsd.dwWidth = 800;
295     ddsd.dwHeight = 600;
296     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
297     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
298     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
299     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
300     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
301     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x0000FF;
302     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x0000FF;
303     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0x000000;
304     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0x000000;
305     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
306     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
307     if(FAILED(rc))
308     {
309         skip("Failed to create surface\n");
310         IDirectDrawSurface_Release(lpDst);
311         return;
312     }
313
314     memset(&fx, 0, sizeof(fx));
315     fx.dwSize = sizeof(fx);
316     fx.ddckSrcColorkey.dwColorSpaceHighValue = 0x110000;
317     fx.ddckSrcColorkey.dwColorSpaceLowValue = 0x110000;
318     fx.ddckDestColorkey.dwColorSpaceHighValue = 0x001100;
319     fx.ddckDestColorkey.dwColorSpaceLowValue = 0x001100;
320
321     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
322     ok(rc==DD_OK,"Lock returned: %x\n",rc);
323     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
324     lpData = (LPDWORD)ddsd2.lpSurface;
325     lpData[0] = 0x000000FF; /* Applies to src blt key in src surface */
326     lpData[1] = 0x00000000; /* Applies to dst blt key in src surface */
327     lpData[2] = 0x00FF0000; /* Dst color key in dst surface */
328     lpData[3] = 0x0000FF00; /* Src color key in dst surface */
329     lpData[4] = 0x00001100; /* Src color key in ddbltfx */
330     lpData[5] = 0x00110000; /* Dst color key in ddbltfx */
331     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
332     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
333
334     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
335     ok(rc==DD_OK,"Lock returned: %x\n",rc);
336     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
337     lpData = (LPDWORD)ddsd2.lpSurface;
338     lpData[0] = 0x55555555;
339     lpData[1] = 0x55555555;
340     lpData[2] = 0x55555555;
341     lpData[3] = 0x55555555;
342     lpData[4] = 0x55555555;
343     lpData[5] = 0x55555555;
344     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
345     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
346
347     /* Test a blit without keying */
348     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, 0, &fx);
349     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
350
351     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
352     ok(rc==DD_OK,"Lock returned: %x\n",rc);
353     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
354     lpData = (LPDWORD)ddsd2.lpSurface;
355     /* Should have copied src data unmodified to dst */
356     ok(lpData[0] == 0x000000FF &&
357        lpData[1] == 0x00000000 &&
358        lpData[2] == 0x00FF0000 &&
359        lpData[3] == 0x0000FF00 &&
360        lpData[4] == 0x00001100 &&
361        lpData[5] == 0x00110000, "Surface data after unkeyed blit does not match\n");
362
363     lpData[0] = 0x55555555;
364     lpData[1] = 0x55555555;
365     lpData[2] = 0x55555555;
366     lpData[3] = 0x55555555;
367     lpData[4] = 0x55555555;
368     lpData[5] = 0x55555555;
369     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
370     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
371
372     /* Src key */
373     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
374     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
375
376     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
377     ok(rc==DD_OK,"Lock returned: %x\n",rc);
378     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
379     lpData = (LPDWORD)ddsd2.lpSurface;
380
381     ok(lpData[0] == 0x55555555 && /* Here the src key applied */
382        lpData[1] == 0x00000000 &&
383        lpData[2] == 0x00FF0000 &&
384        lpData[3] == 0x0000FF00 &&
385        lpData[4] == 0x00001100 &&
386        lpData[5] == 0x00110000, "Surface data after srckey blit does not match\n");
387
388     lpData[0] = 0x55555555;
389     lpData[1] = 0x55555555;
390     lpData[2] = 0x55555555;
391     lpData[3] = 0x55555555;
392     lpData[4] = 0x55555555;
393     lpData[5] = 0x55555555;
394     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
395     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
396
397     /* Src override */
398     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
399     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
400
401     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
402     ok(rc==DD_OK,"Lock returned: %x\n",rc);
403     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
404     lpData = (LPDWORD)ddsd2.lpSurface;
405
406     ok(lpData[0] == 0x000000FF &&
407        lpData[1] == 0x00000000 &&
408        lpData[2] == 0x00FF0000 &&
409        lpData[3] == 0x0000FF00 &&
410        lpData[4] == 0x00001100 &&
411        lpData[5] == 0x55555555, /* Override key applies here */
412        "Surface data after src override key blit does not match\n");
413
414     lpData[0] = 0x55555555;
415     lpData[1] = 0x55555555;
416     lpData[2] = 0x55555555;
417     lpData[3] = 0x55555555;
418     lpData[4] = 0x55555555;
419     lpData[5] = 0x55555555;
420     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
421     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
422
423     /* Src override AND src key. That is not supposed to work */
424     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &fx);
425     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
426
427     /* Verify that the destination is unchanged */
428     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
429     ok(rc==DD_OK,"Lock returned: %x\n",rc);
430     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
431     lpData = (LPDWORD)ddsd2.lpSurface;
432
433     ok(lpData[0] == 0x55555555 &&
434        lpData[1] == 0x55555555 &&
435        lpData[2] == 0x55555555 &&
436        lpData[3] == 0x55555555 &&
437        lpData[4] == 0x55555555 &&
438        lpData[5] == 0x55555555, /* Override key applies here */
439        "Surface data after src key blit with override does not match\n");
440
441     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
442     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
443     lpData[2] = 0x00001100; /* Dest key in override */
444     lpData[3] = 0x00001100; /* Dest key in override */
445     lpData[4] = 0x00000000; /* Dest key in src surface */
446     lpData[5] = 0x00000000; /* Dest key in src surface */
447     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
448     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
449
450     /* Dest key blit */
451     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
452     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
453
454     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
455     ok(rc==DD_OK,"Lock returned: %x\n",rc);
456     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
457     lpData = (LPDWORD)ddsd2.lpSurface;
458
459     /* DirectDraw uses the dest blit key from the SOURCE surface ! */
460     ok(lpData[0] == 0x00ff0000 &&
461        lpData[1] == 0x00ff0000 &&
462        lpData[2] == 0x00001100 &&
463        lpData[3] == 0x00001100 &&
464        lpData[4] == 0x00001100 && /* Key applies here */
465        lpData[5] == 0x00110000,   /* Key applies here */
466        "Surface data after dest key blit does not match\n");
467
468     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
469     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
470     lpData[2] = 0x00001100; /* Dest key in override */
471     lpData[3] = 0x00001100; /* Dest key in override */
472     lpData[4] = 0x00000000; /* Dest key in src surface */
473     lpData[5] = 0x00000000; /* Dest key in src surface */
474     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
475     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
476
477     /* Dest override key blit */
478     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
479     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
480
481     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
482     ok(rc==DD_OK,"Lock returned: %x\n",rc);
483     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
484     lpData = (LPDWORD)ddsd2.lpSurface;
485
486     ok(lpData[0] == 0x00FF0000 &&
487        lpData[1] == 0x00FF0000 &&
488        lpData[2] == 0x00FF0000 && /* Key applies here */
489        lpData[3] == 0x0000FF00 && /* Key applies here */
490        lpData[4] == 0x00000000 &&
491        lpData[5] == 0x00000000,
492        "Surface data after dest key override blit does not match\n");
493
494     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
495     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
496     lpData[2] = 0x00001100; /* Dest key in override */
497     lpData[3] = 0x00001100; /* Dest key in override */
498     lpData[4] = 0x00000000; /* Dest key in src surface */
499     lpData[5] = 0x00000000; /* Dest key in src surface */
500     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
501     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
502
503     /* Dest override key blit. Supposed to fail too */
504     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYDESTOVERRIDE, &fx);
505     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
506
507     /* Check for unchanged data */
508     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
509     ok(rc==DD_OK,"Lock returned: %x\n",rc);
510     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
511     lpData = (LPDWORD)ddsd2.lpSurface;
512
513     ok(lpData[0] == 0x00FF0000 &&
514        lpData[1] == 0x00FF0000 &&
515        lpData[2] == 0x00001100 && /* Key applies here */
516        lpData[3] == 0x00001100 && /* Key applies here */
517        lpData[4] == 0x00000000 &&
518        lpData[5] == 0x00000000,
519        "Surface data with dest key and dest override does not match\n");
520
521     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
522     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
523     lpData[2] = 0x00001100; /* Dest key in override */
524     lpData[3] = 0x00001100; /* Dest key in override */
525     lpData[4] = 0x00000000; /* Dest key in src surface */
526     lpData[5] = 0x00000000; /* Dest key in src surface */
527     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
528     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
529
530     /* Modify the source data a bit to give some more conclusive results */
531     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
532     ok(rc==DD_OK,"Lock returned: %x\n",rc);
533     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
534     lpData = (LPDWORD)ddsd2.lpSurface;
535     lpData[5] = 0x000000FF; /* Applies to src blt key in src surface */
536     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
537     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
538
539     /* Source and destination key */
540     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYSRC, &fx);
541     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
542
543     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
544     ok(rc==DD_OK,"Lock returned: %x\n",rc);
545     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
546     lpData = (LPDWORD)ddsd2.lpSurface;
547
548     ok(lpData[0] == 0x00FF0000 && /* Masked by Destination key */
549        lpData[1] == 0x00FF0000 && /* Masked by Destination key */
550        lpData[2] == 0x00001100 && /* Masked by Destination key */
551        lpData[3] == 0x00001100 && /* Masked by Destination key */
552        lpData[4] == 0x00001100 && /* Allowed by destination key, not masked by source key */
553        lpData[5] == 0x00000000,   /* Allowed by dst key, but masked by source key */
554        "Surface data with src key and dest key blit does not match\n");
555
556     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
557     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
558     lpData[2] = 0x00001100; /* Dest key in override */
559     lpData[3] = 0x00001100; /* Dest key in override */
560     lpData[4] = 0x00000000; /* Dest key in src surface */
561     lpData[5] = 0x00000000; /* Dest key in src surface */
562     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
563     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
564
565     /* Override keys without ddbltfx parameter fail */
566     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, NULL);
567     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
568     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, NULL);
569     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
570
571     /* Try blitting without keys in the source surface*/
572     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, NULL);
573     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
574     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_DESTBLT, NULL);
575     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
576
577     /* That fails now. Do not bother to check that the data is unmodified */
578     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
579     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
580
581     /* Dest key blit still works. Which key is used this time??? */
582     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
583     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
584
585     /* With korrectly passed override keys no key in the surface is needed.
586      * Again, the result was checked before, no need to do that again
587      */
588     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
589     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
590     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
591     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
592
593     IDirectDrawSurface_Release(lpSrc);
594     IDirectDrawSurface_Release(lpDst);
595 }
596
597 static void QueryInterface(void)
598 {
599     LPDIRECTDRAWSURFACE dsurface;
600     DDSURFACEDESC surface;
601     LPVOID object;
602     HRESULT ret;
603
604     /* Create a surface */
605     ZeroMemory(&surface, sizeof(surface));
606     surface.dwSize = sizeof(surface);
607     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
608     surface.dwHeight = 10;
609     surface.dwWidth = 10;
610     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
611     if(ret != DD_OK)
612     {
613         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
614         return;
615     }
616
617     /* Call IUnknown::QueryInterface */
618     ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
619     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %x\n", ret);
620
621     IDirectDrawSurface_Release(dsurface);
622 }
623
624 /* The following tests test which interface is returned by IDirectDrawSurfaceX::GetDDInterface.
625  * It uses refcounts to test that and compares the interface addresses. Partially fits here, and
626  * partially in the refcount test
627  */
628
629 static unsigned long getref(IUnknown *iface)
630 {
631     IUnknown_AddRef(iface);
632     return IUnknown_Release(iface);
633 }
634
635 static void GetDDInterface_1(void)
636 {
637     LPDIRECTDRAWSURFACE dsurface;
638     LPDIRECTDRAWSURFACE2 dsurface2;
639     DDSURFACEDESC surface;
640     HRESULT ret;
641     IDirectDraw2 *dd2;
642     IDirectDraw4 *dd4;
643     IDirectDraw7 *dd7;
644     unsigned long ref1, ref2, ref4, ref7;
645     void *dd;
646
647     /* Create a surface */
648     ZeroMemory(&surface, sizeof(surface));
649     surface.dwSize = sizeof(surface);
650     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
651     surface.dwHeight = 10;
652     surface.dwWidth = 10;
653     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
654     if(ret != DD_OK)
655     {
656         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
657         return;
658     }
659     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
660     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
661     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
662     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
663     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
664     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
665     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
666     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
667
668     ref1 = getref((IUnknown *) lpDD);
669     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
670     ref2 = getref((IUnknown *) dd2);
671     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
672     ref4 = getref((IUnknown *) dd4);
673     ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
674     ref7 = getref((IUnknown *) dd7);
675     ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
676
677
678     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
679     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
680     ok(getref((IUnknown *) lpDD) == ref1 + 1, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
681     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
682     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
683     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
684
685     ok(dd == lpDD, "Returned interface pointer is not equal to the creation interface\n");
686     IUnknown_Release((IUnknown *) dd);
687
688     /* try a NULL pointer */
689     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, NULL);
690     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
691
692     IDirectDraw_Release(dd2);
693     IDirectDraw_Release(dd4);
694     IDirectDraw_Release(dd7);
695     IDirectDrawSurface2_Release(dsurface2);
696     IDirectDrawSurface_Release(dsurface);
697 }
698
699 static void GetDDInterface_2(void)
700 {
701     LPDIRECTDRAWSURFACE dsurface;
702     LPDIRECTDRAWSURFACE2 dsurface2;
703     DDSURFACEDESC surface;
704     HRESULT ret;
705     IDirectDraw2 *dd2;
706     IDirectDraw4 *dd4;
707     IDirectDraw7 *dd7;
708     unsigned long ref1, ref2, ref4, ref7;
709     void *dd;
710
711     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
712     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
713     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
714     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
715     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
716     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
717
718     /* Create a surface */
719     ZeroMemory(&surface, sizeof(surface));
720     surface.dwSize = sizeof(surface);
721     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
722     surface.dwHeight = 10;
723     surface.dwWidth = 10;
724     ret = IDirectDraw2_CreateSurface(dd2, &surface, &dsurface, NULL);
725     if(ret != DD_OK)
726     {
727         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
728         return;
729     }
730     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
731     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
732
733     ref1 = getref((IUnknown *) lpDD);
734     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
735     ref2 = getref((IUnknown *) dd2);
736     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
737     ref4 = getref((IUnknown *) dd4);
738     ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
739     ref7 = getref((IUnknown *) dd7);
740     ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
741
742
743     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
744     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
745     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
746     ok(getref((IUnknown *) dd2) == ref2 + 1, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
747     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
748     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
749
750     ok(dd == dd2, "Returned interface pointer is not equal to the creation interface\n");
751     IUnknown_Release((IUnknown *) dd);
752
753     IDirectDraw_Release(dd2);
754     IDirectDraw_Release(dd4);
755     IDirectDraw_Release(dd7);
756     IDirectDrawSurface2_Release(dsurface2);
757     IDirectDrawSurface_Release(dsurface);
758 }
759
760 static void GetDDInterface_4(void)
761 {
762     LPDIRECTDRAWSURFACE2 dsurface2;
763     LPDIRECTDRAWSURFACE4 dsurface4;
764     DDSURFACEDESC2 surface;
765     HRESULT ret;
766     IDirectDraw2 *dd2;
767     IDirectDraw4 *dd4;
768     IDirectDraw7 *dd7;
769     unsigned long ref1, ref2, ref4, ref7;
770     void *dd;
771
772     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
773     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
774     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
775     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
776     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
777     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
778
779     /* Create a surface */
780     ZeroMemory(&surface, sizeof(surface));
781     surface.dwSize = sizeof(surface);
782     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
783     surface.dwHeight = 10;
784     surface.dwWidth = 10;
785     ret = IDirectDraw4_CreateSurface(dd4, &surface, &dsurface4, NULL);
786     if(ret != DD_OK)
787     {
788         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
789         return;
790     }
791     ret = IDirectDrawSurface4_QueryInterface(dsurface4, &IID_IDirectDrawSurface2, (void **) &dsurface2);
792     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
793
794     ref1 = getref((IUnknown *) lpDD);
795     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
796     ref2 = getref((IUnknown *) dd2);
797     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
798     ref4 = getref((IUnknown *) dd4);
799     ok(ref4 == 2, "IDirectDraw4 refcount is %ld\n", ref4);
800     ref7 = getref((IUnknown *) dd7);
801     ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
802
803     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
804     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
805     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
806     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
807     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
808     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
809
810     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
811     IUnknown_Release((IUnknown *) dd);
812
813     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
814     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
815     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
816     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
817     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
818     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
819     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
820
821     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
822     IUnknown_Release((IUnknown *) dd);
823
824     IDirectDraw_Release(dd2);
825     IDirectDraw_Release(dd4);
826     IDirectDraw_Release(dd7);
827     IDirectDrawSurface4_Release(dsurface4);
828     IDirectDrawSurface2_Release(dsurface2);
829 }
830
831 static void GetDDInterface_7(void)
832 {
833     LPDIRECTDRAWSURFACE4 dsurface4;
834     LPDIRECTDRAWSURFACE7 dsurface7;
835     DDSURFACEDESC2 surface;
836     HRESULT ret;
837     IDirectDraw2 *dd2;
838     IDirectDraw4 *dd4;
839     IDirectDraw7 *dd7;
840     unsigned long ref1, ref2, ref4, ref7;
841     void *dd;
842
843     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
844     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
845     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
846     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
847     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
848     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
849
850     /* Create a surface */
851     ZeroMemory(&surface, sizeof(surface));
852     surface.dwSize = sizeof(surface);
853     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
854     surface.dwHeight = 10;
855     surface.dwWidth = 10;
856     ret = IDirectDraw7_CreateSurface(dd7, &surface, &dsurface7, NULL);
857     if(ret != DD_OK)
858     {
859         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
860         return;
861     }
862     ret = IDirectDrawSurface7_QueryInterface(dsurface7, &IID_IDirectDrawSurface4, (void **) &dsurface4);
863     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
864
865     ref1 = getref((IUnknown *) lpDD);
866     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
867     ref2 = getref((IUnknown *) dd2);
868     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
869     ref4 = getref((IUnknown *) dd4);
870     ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
871     ref7 = getref((IUnknown *) dd7);
872     ok(ref7 == 2, "IDirectDraw7 refcount is %ld\n", ref7);
873
874     ret = IDirectDrawSurface7_GetDDInterface(dsurface7, &dd);
875     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
876     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
877     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
878     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
879     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
880
881     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
882     IUnknown_Release((IUnknown *) dd);
883
884     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
885     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
886     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
887     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
888     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
889     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
890     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
891
892     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
893     IUnknown_Release((IUnknown *) dd);
894
895     IDirectDraw_Release(dd2);
896     IDirectDraw_Release(dd4);
897     IDirectDraw_Release(dd7);
898     IDirectDrawSurface4_Release(dsurface4);
899     IDirectDrawSurface7_Release(dsurface7);
900 }
901
902 #define MAXEXPECTED 8  /* Can match up to 8 expected surfaces */
903 struct enumstruct
904 {
905     IDirectDrawSurface *expected[MAXEXPECTED];
906     UINT count;
907 };
908
909 static HRESULT WINAPI enumCB(IDirectDrawSurface *surf, DDSURFACEDESC *desc, void *ctx)
910 {
911     int i;
912     BOOL found = FALSE;
913
914     for(i = 0; i < MAXEXPECTED; i++)
915     {
916         if(((struct enumstruct *)ctx)->expected[i] == surf) found = TRUE;
917     }
918
919     ok(found, "Unexpected surface %p enumerated\n", surf);
920     ((struct enumstruct *)ctx)->count++;
921     IDirectDrawSurface_Release(surf);
922     return DDENUMRET_OK;
923 }
924
925 static void EnumTest(void)
926 {
927     HRESULT rc;
928     DDSURFACEDESC ddsd;
929     IDirectDrawSurface *surface;
930     struct enumstruct ctx;
931
932     ddsd.dwSize = sizeof(ddsd);
933     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
934     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
935     U2(ddsd).dwMipMapCount = 3;
936     ddsd.dwWidth = 32;
937     ddsd.dwHeight = 32;
938     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
939     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
940
941     memset(&ctx, 0, sizeof(ctx));
942     ctx.expected[0] = surface;
943     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[0], &ddsd.ddsCaps, &ctx.expected[1]);
944     ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
945     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[1], &ddsd.ddsCaps, &ctx.expected[2]);
946     ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
947     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[2], &ddsd.ddsCaps, &ctx.expected[3]);
948     ok(rc == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", rc);
949     ctx.count = 0;
950
951     rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, &ddsd, (void *) &ctx, enumCB);
952     ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
953     ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
954
955     IDirectDrawSurface_Release(ctx.expected[2]);
956     IDirectDrawSurface_Release(ctx.expected[1]);
957     IDirectDrawSurface_Release(surface);
958 }
959
960 HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
961 {
962     UINT *num = context;
963     (*num)++;
964     IDirectDrawSurface_Release(surface);
965     return DDENUMRET_OK;
966 }
967
968 static void AttachmentTest7(void)
969 {
970     HRESULT hr;
971     IDirectDraw7 *dd7;
972     IDirectDrawSurface7 *surface1, *surface2, *surface3, *surface4;
973     DDSURFACEDESC2 ddsd;
974     UINT num;
975     DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0};
976     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
977
978     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
979     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
980
981     memset(&ddsd, 0, sizeof(ddsd));
982     ddsd.dwSize = sizeof(ddsd);
983     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
984     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
985     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
986     ddsd.dwWidth = 128;
987     ddsd.dwHeight = 128;
988     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
989     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
990
991     /* ROOT */
992     num = 0;
993     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
994     ok(num == 1, "Mipmap root has %d surfaces attached, expected 1\n", num);
995     /* DONE ROOT */
996
997     /* LEVEL 1 */
998     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
999     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1000     num = 0;
1001     IDirectDrawSurface7_EnumAttachedSurfaces(surface2, &num, SurfaceCounter);
1002     ok(num == 1, "First mip level has %d surfaces attached, expected 1\n", num);
1003     /* DONE LEVEL 1 */
1004
1005     /* LEVEL 2 */
1006     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1007     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1008     IDirectDrawSurface7_Release(surface2);
1009     num = 0;
1010     IDirectDrawSurface7_EnumAttachedSurfaces(surface3, &num, SurfaceCounter);
1011     ok(num == 0, "Secound mip level has %d surfaces attached, expected 1\n", num);
1012     /* Done level 2 */
1013     /* Mip level 3 is still needed */
1014
1015     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1016     memset(&ddsd, 0, sizeof(ddsd));
1017     ddsd.dwSize = sizeof(ddsd);
1018     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1019     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1020     ddsd.dwWidth = 16;
1021     ddsd.dwHeight = 16;
1022     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1023     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1024
1025     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1026     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1027     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1028     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1029     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1030     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1031     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1032     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1033
1034     IDirectDrawSurface7_Release(surface2);
1035
1036     memset(&ddsd, 0, sizeof(ddsd));
1037     ddsd.dwSize = sizeof(ddsd);
1038     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1039     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1040     ddsd.dwWidth = 16;
1041     ddsd.dwHeight = 16;
1042     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1043     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1044
1045     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1046     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1047     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1048     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1049     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1050     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1051     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1052     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1053
1054     IDirectDrawSurface7_Release(surface3);
1055     IDirectDrawSurface7_Release(surface2);
1056     IDirectDrawSurface7_Release(surface1);
1057
1058     hr = IDirectDraw7_SetCooperativeLevel(dd7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1059     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1060
1061     memset(&ddsd, 0, sizeof(ddsd));
1062     ddsd.dwSize = sizeof(ddsd);
1063     ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
1064     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
1065     ddsd.dwBackBufferCount = 2;
1066     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1067     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1068
1069     num = 0;
1070     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1071     ok(num == 1, "Primary surface has %d surfaces attached, expected 1\n", num);
1072     IDirectDrawSurface7_Release(surface1);
1073
1074     /* Those are some invalid descriptions, no need to test attachments with them */
1075     memset(&ddsd, 0, sizeof(ddsd));
1076     ddsd.dwSize = sizeof(ddsd);
1077     ddsd.dwFlags = DDSD_CAPS;
1078     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1079     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1080     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1081     memset(&ddsd, 0, sizeof(ddsd));
1082     ddsd.dwSize = sizeof(ddsd);
1083     ddsd.dwFlags = DDSD_CAPS;
1084     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1085     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1086     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1087
1088     /* Try a single primary and two offscreen plain surfaces */
1089     memset(&ddsd, 0, sizeof(ddsd));
1090     ddsd.dwSize = sizeof(ddsd);
1091     ddsd.dwFlags = DDSD_CAPS;
1092     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1093     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1094     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1095
1096     memset(&ddsd, 0, sizeof(ddsd));
1097     ddsd.dwSize = sizeof(ddsd);
1098     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1099     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1100     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1101     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1102     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1103     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1104
1105     memset(&ddsd, 0, sizeof(ddsd));
1106     ddsd.dwSize = sizeof(ddsd);
1107     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1108     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1109     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1110     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1111     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface3, NULL);
1112     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1113
1114     /* This one has a different size */
1115     memset(&ddsd, 0, sizeof(ddsd));
1116     ddsd.dwSize = sizeof(ddsd);
1117     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1118     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1119     ddsd.dwWidth = 128;
1120     ddsd.dwHeight = 128;
1121     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface4, NULL);
1122     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1123
1124     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1125     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1126     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1127     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1128     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1129     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1130     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1131     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1132     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1133     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1134
1135     IDirectDrawSurface7_Release(surface4);
1136     IDirectDrawSurface7_Release(surface3);
1137     IDirectDrawSurface7_Release(surface2);
1138     IDirectDrawSurface7_Release(surface1);
1139
1140     hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL);
1141     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1142     IDirectDraw7_Release(dd7);
1143 }
1144
1145 static void AttachmentTest(void)
1146 {
1147     HRESULT hr;
1148     IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
1149     DDSURFACEDESC ddsd;
1150     DDSCAPS caps = {DDSCAPS_TEXTURE};
1151     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1152
1153     memset(&ddsd, 0, sizeof(ddsd));
1154     ddsd.dwSize = sizeof(ddsd);
1155     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1156     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1157     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1158     ddsd.dwWidth = 128;
1159     ddsd.dwHeight = 128;
1160     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1161     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1162
1163     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1164     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1165     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1166     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1167
1168     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1169     memset(&ddsd, 0, sizeof(ddsd));
1170     ddsd.dwSize = sizeof(ddsd);
1171     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1172     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1173     ddsd.dwWidth = 16;
1174     ddsd.dwHeight = 16;
1175     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1176     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1177
1178     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1179     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1180     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1181     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1182     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
1183     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1184     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1185     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1186     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
1187     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 64x64 texture sublevel returned %08x\n", hr);
1188     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1189     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 texture returned %08x\n", hr);
1190
1191     IDirectDrawSurface7_Release(surface4);
1192
1193     memset(&ddsd, 0, sizeof(ddsd));
1194     ddsd.dwSize = sizeof(ddsd);
1195     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1196     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1197     ddsd.dwWidth = 16;
1198     ddsd.dwHeight = 16;
1199     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1200     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1201
1202     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1203     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1204     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1205     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1206     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
1207     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1208     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1209     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1210     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
1211     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1212     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1213     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 offscreen plain surface returned %08x\n", hr);
1214
1215     IDirectDrawSurface7_Release(surface4);
1216     IDirectDrawSurface7_Release(surface3);
1217     IDirectDrawSurface7_Release(surface2);
1218     IDirectDrawSurface7_Release(surface1);
1219
1220     hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1221     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1222
1223     /* Creating a back buffer as-is is not allowed, no need to perform attachment tests */
1224     memset(&ddsd, 0, sizeof(ddsd));
1225     ddsd.dwSize = sizeof(ddsd);
1226     ddsd.dwFlags = DDSD_CAPS;
1227     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1228     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1229     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1230     /* This old ddraw version happily creates explicit front buffers */
1231     memset(&ddsd, 0, sizeof(ddsd));
1232     ddsd.dwSize = sizeof(ddsd);
1233     ddsd.dwFlags = DDSD_CAPS;
1234     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1235     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1236     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1237     IDirectDrawSurface_Release(surface1);
1238
1239     /* Try a single primary and two offscreen plain surfaces */
1240     memset(&ddsd, 0, sizeof(ddsd));
1241     ddsd.dwSize = sizeof(ddsd);
1242     ddsd.dwFlags = DDSD_CAPS;
1243     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1244     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1245     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1246
1247     memset(&ddsd, 0, sizeof(ddsd));
1248     ddsd.dwSize = sizeof(ddsd);
1249     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1250     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1251     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1252     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1253     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1254     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1255
1256     memset(&ddsd, 0, sizeof(ddsd));
1257     ddsd.dwSize = sizeof(ddsd);
1258     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1259     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1260     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1261     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1262     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
1263     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1264
1265     /* This one has a different size */
1266     memset(&ddsd, 0, sizeof(ddsd));
1267     ddsd.dwSize = sizeof(ddsd);
1268     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1269     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1270     ddsd.dwWidth = 128;
1271     ddsd.dwHeight = 128;
1272     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1273     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1274
1275     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
1276     ok(hr == DD_OK, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1277     /* Try the reverse without detaching first */
1278     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1279     ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
1280     hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1281     ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1282     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1283     ok(hr == DD_OK, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1284     /* Try to detach reversed */
1285     hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1286     ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
1287     /* Now the proper detach */
1288     hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
1289     ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1290     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
1291     ok(hr == DD_OK, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1292     hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
1293     ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1294     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
1295     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1296     hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
1297     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1298
1299     IDirectDrawSurface_Release(surface4);
1300     IDirectDrawSurface_Release(surface3);
1301     IDirectDrawSurface_Release(surface2);
1302     IDirectDrawSurface_Release(surface1);
1303
1304     hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
1305     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1306
1307     DestroyWindow(window);
1308 }
1309
1310 struct compare
1311 {
1312     DWORD width, height;
1313     DWORD caps, caps2;
1314     UINT mips;
1315 };
1316
1317 HRESULT WINAPI CubeTestLvl2Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1318 {
1319     UINT *mips = context;
1320
1321     (*mips)++;
1322     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1323                                              context,
1324                                              CubeTestLvl2Enum);
1325
1326     return DDENUMRET_OK;
1327 }
1328
1329 HRESULT WINAPI CubeTestLvl1Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1330 {
1331     UINT mips = 0;
1332     UINT *num = (UINT *) context;
1333     static const struct compare expected[] =
1334     {
1335         {
1336             128, 128,
1337             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1338             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ,
1339             7
1340         },
1341         {
1342             128, 128,
1343             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1344             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ,
1345             7
1346         },
1347         {
1348             128, 128,
1349             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1350             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY,
1351             7
1352         },
1353         {
1354             128, 128,
1355             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1356             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY,
1357             7
1358         },
1359         {
1360             128, 128,
1361             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1362             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX,
1363             7
1364         },
1365         {
1366             64, 64, /* This is the first mipmap */
1367             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1368             DDSCAPS2_MIPMAPSUBLEVEL | DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX,
1369             6
1370         },
1371     };
1372
1373     mips = 0;
1374     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1375                                              &mips,
1376                                              CubeTestLvl2Enum);
1377
1378     ok(desc->dwWidth == expected[*num].width, "Surface width is %d expected %d\n", desc->dwWidth, expected[*num].width);
1379     ok(desc->dwHeight == expected[*num].height, "Surface height is %d expected %d\n", desc->dwHeight, expected[*num].height);
1380     ok(desc->ddsCaps.dwCaps == expected[*num].caps, "Surface caps are %08x expected %08x\n", desc->ddsCaps.dwCaps, expected[*num].caps);
1381     ok(desc->ddsCaps.dwCaps2 == expected[*num].caps2, "Surface caps2 are %08x expected %08x\n", desc->ddsCaps.dwCaps2, expected[*num].caps2);
1382     ok(mips == expected[*num].mips, "Surface has %d mipmaps, expected %d\n", mips, expected[*num].mips);
1383
1384     (*num)++;
1385
1386     IDirectDrawSurface7_Release(surface);
1387
1388     return DDENUMRET_OK;
1389 }
1390
1391 static void CubeMapTest(void)
1392 {
1393     IDirectDraw7 *dd7 = NULL;
1394     IDirectDrawSurface7 *cubemap;
1395     DDSURFACEDESC2 ddsd;
1396     HRESULT hr;
1397     UINT num = 0;
1398     struct enumstruct ctx;
1399
1400     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1401     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1402
1403     memset(&ddsd, 0, sizeof(ddsd));
1404     ddsd.dwSize = sizeof(ddsd);
1405     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1406     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1407     ddsd.dwWidth = 128;
1408     ddsd.dwHeight = 128;
1409     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1410     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1411
1412     /* D3DFMT_R5G6B5 */
1413     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1414     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1415     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1416     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1417     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1418
1419     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1420     ok(hr == DD_OK, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1421
1422     hr = IDirectDrawSurface7_GetSurfaceDesc(cubemap, &ddsd);
1423     ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
1424     ok(ddsd.ddsCaps.dwCaps == (DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX),
1425        "Root Caps are %08x\n", ddsd.ddsCaps.dwCaps);
1426     ok(ddsd.ddsCaps.dwCaps2 == (DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP),
1427        "Root Caps2 are %08x\n", ddsd.ddsCaps.dwCaps2);
1428
1429     IDirectDrawSurface7_EnumAttachedSurfaces(cubemap,
1430                                              &num,
1431                                              CubeTestLvl1Enum);
1432     trace("Enumerated %d surfaces in total\n", num);
1433     ok(num == 6, "Surface has %d attachments\n", num);
1434     IDirectDrawSurface7_Release(cubemap);
1435
1436     /* What happens if I do not specify any faces? */
1437     memset(&ddsd, 0, sizeof(ddsd));
1438     ddsd.dwSize = sizeof(ddsd);
1439     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1440     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1441     ddsd.dwWidth = 128;
1442     ddsd.dwHeight = 128;
1443     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1444     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP;
1445
1446     /* D3DFMT_R5G6B5 */
1447     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1448     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1449     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1450     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1451     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1452
1453     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1454     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7::CreateSurface asking for a cube map without faces returned %08x\n", hr);
1455
1456     /* Cube map faces without a cube map? */
1457     memset(&ddsd, 0, sizeof(ddsd));
1458     ddsd.dwSize = sizeof(ddsd);
1459     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1460     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1461     ddsd.dwWidth = 128;
1462     ddsd.dwHeight = 128;
1463     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1464     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_ALLFACES;
1465
1466     /* D3DFMT_R5G6B5 */
1467     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1468     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1469     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1470     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1471     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1472
1473     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1474     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1475
1476     memset(&ddsd, 0, sizeof(ddsd));
1477     ddsd.dwSize = sizeof(ddsd);
1478     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1479     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1480     ddsd.dwWidth = 128;
1481     ddsd.dwHeight = 128;
1482     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1483     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEX;
1484
1485     /* D3DFMT_R5G6B5 */
1486     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1487     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1488     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1489     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1490     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1491
1492     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1493     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1494
1495     /* Make sure everything is cleaned up properly. Use the enumSurfaces test infrastructure */
1496     memset(&ctx, 0, sizeof(ctx));
1497     memset(&ddsd, 0, sizeof(ddsd));
1498     ddsd.dwSize = sizeof(DDSURFACEDESC);
1499     hr = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, (DDSURFACEDESC *) &ddsd, (void *) &ctx, enumCB);
1500     ok(hr == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", hr);
1501     ok(ctx.count == 0, "%d surfaces enumerated, expected 0\n", ctx.count);
1502
1503     IDirectDraw7_Release(dd7);
1504 }
1505
1506 static void test_lockrect_invalid(void)
1507 {
1508     unsigned int i, j;
1509
1510     RECT valid[] = {
1511         {60, 60, 68, 68},
1512         {60, 60, 60, 68},
1513         {60, 60, 68, 60},
1514         {120, 60, 128, 68},
1515         {60, 120, 68, 128},
1516     };
1517
1518     RECT invalid[] = {
1519         {68, 60, 60, 68},       /* left > right */
1520         {60, 68, 68, 60},       /* top > bottom */
1521         {-8, 60,  0, 68},       /* left < surface */
1522         {60, -8, 68,  0},       /* top < surface */
1523         {-16, 60, -8, 68},      /* right < surface */
1524         {60, -16, 68, -8},      /* bottom < surface */
1525         {60, 60, 136, 68},      /* right > surface */
1526         {60, 60, 68, 136},      /* bottom > surface */
1527         {136, 60, 144, 68},     /* left > surface */
1528         {60, 136, 68, 144},     /* top > surface */
1529     };
1530
1531     const DWORD dds_caps[] = {
1532         DDSCAPS_OFFSCREENPLAIN,
1533         DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE,
1534     };
1535
1536     for (j = 0; j < (sizeof(dds_caps) / sizeof(*dds_caps)); ++j)
1537     {
1538         IDirectDrawSurface *surface = 0;
1539         DDSURFACEDESC surface_desc = {0};
1540         DDSURFACEDESC locked_desc = {0};
1541         HRESULT hr;
1542
1543         surface_desc.dwSize = sizeof(surface_desc);
1544         surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
1545         surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1546         surface_desc.ddsCaps.dwCaps = dds_caps[j];
1547         surface_desc.dwWidth = 128;
1548         surface_desc.dwHeight = 128;
1549         surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
1550         U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
1551         U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xFF0000;
1552         U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00FF00;
1553         U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000FF;
1554
1555         hr = IDirectDraw_CreateSurface(lpDD, &surface_desc, &surface, NULL);
1556         ok(SUCCEEDED(hr), "CreateSurface failed (0x%08x)\n", hr);
1557
1558         for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i)
1559         {
1560             RECT *rect = &valid[i];
1561
1562             memset(&locked_desc, 0, sizeof(locked_desc));
1563             locked_desc.dwSize = sizeof(locked_desc);
1564
1565             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1566             ok(SUCCEEDED(hr), "Lock failed (0x%08x) for rect [%d, %d]->[%d, %d]\n",
1567                     hr, rect->left, rect->top, rect->right, rect->bottom);
1568
1569             hr = IDirectDrawSurface_Unlock(surface, NULL);
1570             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1571         }
1572
1573         for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i)
1574         {
1575             RECT *rect = &invalid[i];
1576
1577             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1578             ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for rect [%d, %d]->[%d, %d]"
1579                     ", expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, rect->left, rect->top,
1580                     rect->right, rect->bottom, DDERR_INVALIDPARAMS);
1581         }
1582
1583         IDirectDrawSurface_Release(surface);
1584     }
1585 }
1586
1587 static void CompressedTest(void)
1588 {
1589     HRESULT hr;
1590     IDirectDrawSurface7 *surface;
1591     DDSURFACEDESC2 ddsd, ddsd2;
1592     IDirectDraw7 *dd7 = NULL;
1593     RECT r = { 0, 0, 128, 128 };
1594     RECT r2 = { 32, 32, 64, 64 };
1595
1596     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1597     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1598
1599     memset(&ddsd, 0, sizeof(ddsd));
1600     ddsd.dwSize = sizeof(ddsd);
1601     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1602     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1603     ddsd.dwWidth = 128;
1604     ddsd.dwHeight = 128;
1605     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
1606     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
1607     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1608
1609     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1610     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1611
1612     memset(&ddsd2, 0, sizeof(ddsd2));
1613     ddsd2.dwSize = sizeof(ddsd2);
1614     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1615     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1616     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1617
1618     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1619        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1620     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1621     ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1622     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1623        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1624     ok(ddsd2.dwLinearSize == 8192, "Linear size is %d\n", ddsd2.dwLinearSize);
1625     ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1626     IDirectDrawSurface7_Release(surface);
1627
1628     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1629     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1630     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1631
1632     memset(&ddsd2, 0, sizeof(ddsd2));
1633     ddsd2.dwSize = sizeof(ddsd2);
1634     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1635     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1636     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1637
1638     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1639        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1640     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1641     ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1642     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1643        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1644     ok(ddsd2.dwLinearSize == 16384, "Linear size is %d\n", ddsd2.dwLinearSize);
1645     IDirectDrawSurface7_Release(surface);
1646
1647     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1648     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1649     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1650
1651     memset(&ddsd2, 0, sizeof(ddsd2));
1652     ddsd2.dwSize = sizeof(ddsd2);
1653     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1654     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1655     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1656
1657     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1658        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1659     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1660     ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1661     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1662        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1663     ok(ddsd2.dwLinearSize == 16384, "Linear size is %d\n", ddsd2.dwLinearSize);
1664     ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
1665
1666     memset(&ddsd2, 0, sizeof(ddsd2));
1667     ddsd2.dwSize = sizeof(ddsd2);
1668     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1669
1670     /* Show that the description is not changed when locking the surface. What is really interesting
1671      * about this is that DDSD_LPSURFACE isn't set.
1672      */
1673     hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
1674     ok(hr == DD_OK, "Lock returned %08x\n", hr);
1675
1676     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1677        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1678     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1679     ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1680     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1681        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1682     ok(ddsd2.dwLinearSize == 16384, "Linear size is %d\n", ddsd2.dwLinearSize);
1683     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1684
1685     hr = IDirectDrawSurface7_Unlock(surface, NULL);
1686     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1687
1688     /* Now what about a locking rect?  */
1689     hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
1690     ok(hr == DD_OK, "Lock returned %08x\n", hr);
1691
1692     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1693        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1694     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1695     ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1696     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1697        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1698     ok(ddsd2.dwLinearSize == 16384, "Linear size is %d\n", ddsd2.dwLinearSize);
1699     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1700
1701     hr = IDirectDrawSurface7_Unlock(surface, &r);
1702     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1703
1704     /* Now what about a different locking offset? */
1705     hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
1706     ok(hr == DD_OK, "Lock returned %08x\n", hr);
1707
1708     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1709        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1710     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1711     ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1712     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1713        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1714     ok(ddsd2.dwLinearSize == 16384, "Linear size is %d\n", ddsd2.dwLinearSize);
1715     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1716
1717     hr = IDirectDrawSurface7_Unlock(surface, &r2);
1718     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1719     IDirectDrawSurface7_Release(surface);
1720
1721     /* Try this with video memory. A kind of surprise. It still has the LINEARSIZE flag set,
1722      * but seems to have a pitch instead.
1723      */
1724     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
1725     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1726
1727     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1728     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW, "CreateSurface returned %08x\n", hr);
1729
1730     /* Not supported everywhere */
1731     if(SUCCEEDED(hr))
1732     {
1733         memset(&ddsd2, 0, sizeof(ddsd2));
1734         ddsd2.dwSize = sizeof(ddsd2);
1735         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1736         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1737         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1738
1739         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1740         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1741         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1742         ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1743         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1744         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1745         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1746         ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1747         IDirectDrawSurface7_Release(surface);
1748
1749         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1750         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1751         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1752
1753         memset(&ddsd2, 0, sizeof(ddsd2));
1754         ddsd2.dwSize = sizeof(ddsd2);
1755         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1756         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1757         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1758
1759         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1760         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1761         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1762         ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1763         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1764         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1765         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1766         IDirectDrawSurface7_Release(surface);
1767
1768         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1769         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1770         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1771
1772         memset(&ddsd2, 0, sizeof(ddsd2));
1773         ddsd2.dwSize = sizeof(ddsd2);
1774         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1775         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1776         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1777
1778         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1779         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1780         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1781         ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1782         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1783         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1784         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1785         ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
1786
1787         memset(&ddsd2, 0, sizeof(ddsd2));
1788         ddsd2.dwSize = sizeof(ddsd2);
1789         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1790
1791         /* Show that the description is not changed when locking the surface. What is really interesting
1792         * about this is that DDSD_LPSURFACE isn't set.
1793         */
1794         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
1795         ok(hr == DD_OK, "Lock returned %08x\n", hr);
1796
1797         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1798         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1799         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1800         ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1801         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1802         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1803         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1804         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1805
1806         hr = IDirectDrawSurface7_Unlock(surface, NULL);
1807         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1808
1809         /* Now what about a locking rect?  */
1810         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
1811         ok(hr == DD_OK, "Lock returned %08x\n", hr);
1812
1813         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1814         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1815         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1816         ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1817         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1818         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1819         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1820         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1821
1822         hr = IDirectDrawSurface7_Unlock(surface, &r);
1823         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1824
1825         /* Now what about a different locking offset? */
1826         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
1827         ok(hr == DD_OK, "Lock returned %08x\n", hr);
1828
1829         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1830         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1831         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1832         ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1833         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1834         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1835         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1836         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1837
1838         hr = IDirectDrawSurface7_Unlock(surface, &r2);
1839         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1840
1841         IDirectDrawSurface7_Release(surface);
1842     }
1843     else
1844     {
1845         skip("Hardware DXTN textures not supported\n");
1846     }
1847
1848     /* What happens to managed textures? Interestingly, Windows reports them as beeing in system
1849      * memory. The linear size fits again.
1850      */
1851     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1852     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
1853     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1854
1855     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1856     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW, "CreateSurface returned %08x\n", hr);
1857
1858     /* Not supported everywhere */
1859     if(SUCCEEDED(hr))
1860     {
1861         memset(&ddsd2, 0, sizeof(ddsd2));
1862         ddsd2.dwSize = sizeof(ddsd2);
1863         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1864         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1865         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1866
1867         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1868         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1869         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1870         ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1871         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1872         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1873         ok(ddsd2.dwLinearSize == 8192, "Linear size is %d\n", ddsd2.dwLinearSize);
1874         ok(ddsd2.ddsCaps.dwCaps2 == DDSCAPS2_TEXTUREMANAGE, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1875         IDirectDrawSurface7_Release(surface);
1876
1877         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1878         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1879         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1880
1881         memset(&ddsd2, 0, sizeof(ddsd2));
1882         ddsd2.dwSize = sizeof(ddsd2);
1883         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1884         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1885         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1886
1887         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1888         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1889         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1890         ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1891         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1892         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1893         ok(ddsd2.dwLinearSize == 16384, "Linear size is %d\n", ddsd2.dwLinearSize);
1894         IDirectDrawSurface7_Release(surface);
1895
1896         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1897         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1898         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1899
1900         memset(&ddsd2, 0, sizeof(ddsd2));
1901         ddsd2.dwSize = sizeof(ddsd2);
1902         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1903         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1904         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1905
1906         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1907         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1908         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1909         ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1910         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1911         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1912         ok(ddsd2.dwLinearSize == 16384, "Linear size is %d\n", ddsd2.dwLinearSize);
1913         ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
1914
1915         memset(&ddsd2, 0, sizeof(ddsd2));
1916         ddsd2.dwSize = sizeof(ddsd2);
1917         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1918
1919         /* Show that the description is not changed when locking the surface. What is really interesting
1920         * about this is that DDSD_LPSURFACE isn't set.
1921         */
1922         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
1923         ok(hr == DD_OK, "Lock returned %08x\n", hr);
1924
1925         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1926         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1927         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1928         ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1929         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1930         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1931         ok(ddsd2.dwLinearSize == 16384, "Linear size is %d\n", ddsd2.dwLinearSize);
1932         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1933
1934         hr = IDirectDrawSurface7_Unlock(surface, NULL);
1935         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1936
1937         /* Now what about a locking rect?  */
1938         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
1939         ok(hr == DD_OK, "Lock returned %08x\n", hr);
1940
1941         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1942         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1943         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1944         ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1945         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1946         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1947         ok(ddsd2.dwLinearSize == 16384, "\"Linear\" size is %d\n", ddsd2.dwLinearSize);
1948         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1949
1950         hr = IDirectDrawSurface7_Unlock(surface, &r);
1951         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1952
1953         /* Now what about a different locking offset? */
1954         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
1955         ok(hr == DD_OK, "Lock returned %08x\n", hr);
1956
1957         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1958         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1959         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1960         ok(U4(ddsd2).ddpfPixelFormat.dwRGBBitCount == 0, "RGB bitcount: %08x\n", U4(ddsd2).ddpfPixelFormat.dwRGBBitCount);
1961         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1962         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1963         ok(ddsd2.dwLinearSize == 16384, "\"Linear\" size is %d\n", ddsd2.dwLinearSize);
1964         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1965
1966         hr = IDirectDrawSurface7_Unlock(surface, &r2);
1967         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1968
1969         IDirectDrawSurface7_Release(surface);
1970     }
1971     else
1972     {
1973         skip("Hardware DXTN textures not supported\n");
1974     }
1975
1976     IDirectDraw7_Release(dd7);
1977 }
1978
1979 static void SizeTest(void)
1980 {
1981     LPDIRECTDRAWSURFACE dsurface = NULL;
1982     DDSURFACEDESC desc;
1983     HRESULT ret;
1984     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1985
1986     /* Create an offscreen surface surface without a size */
1987     ZeroMemory(&desc, sizeof(desc));
1988     desc.dwSize = sizeof(desc);
1989     desc.dwFlags = DDSD_CAPS;
1990     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
1991     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1992     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without a size info returned %08x\n", ret);
1993     if(dsurface)
1994     {
1995         trace("Surface at %p\n", dsurface);
1996         IDirectDrawSurface_Release(dsurface);
1997         dsurface = NULL;
1998     }
1999
2000     /* Create an offscreen surface surface with only a width parameter */
2001     ZeroMemory(&desc, sizeof(desc));
2002     desc.dwSize = sizeof(desc);
2003     desc.dwFlags = DDSD_CAPS | DDSD_WIDTH;
2004     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2005     desc.dwWidth = 128;
2006     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2007     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without hight info returned %08x\n", ret);
2008     if(dsurface)
2009     {
2010         IDirectDrawSurface_Release(dsurface);
2011         dsurface = NULL;
2012     }
2013
2014     /* Create an offscreen surface surface with only a height parameter */
2015     ZeroMemory(&desc, sizeof(desc));
2016     desc.dwSize = sizeof(desc);
2017     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT;
2018     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2019     desc.dwHeight = 128;
2020     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2021     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without width info returned %08x\n", ret);
2022     if(dsurface)
2023     {
2024         IDirectDrawSurface_Release(dsurface);
2025         dsurface = NULL;
2026     }
2027
2028     /* Sanity check */
2029     ZeroMemory(&desc, sizeof(desc));
2030     desc.dwSize = sizeof(desc);
2031     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2032     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2033     desc.dwHeight = 128;
2034     desc.dwWidth = 128;
2035     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2036     ok(ret == DD_OK, "Creating an offscreen plain surface with width and height info returned %08x\n", ret);
2037     if(dsurface)
2038     {
2039         IDirectDrawSurface_Release(dsurface);
2040         dsurface = NULL;
2041     }
2042
2043     /* Test a primary surface size */
2044     ret = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_NORMAL);
2045     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2046
2047     ZeroMemory(&desc, sizeof(desc));
2048     desc.dwSize = sizeof(desc);
2049     desc.dwFlags = DDSD_CAPS;
2050     desc.ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
2051     desc.dwHeight = 128; /* Keep them set to  check what happens */
2052     desc.dwWidth = 128; /* Keep them set to  check what happens */
2053     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2054     ok(ret == DD_OK, "Creating a primary surface without width and height info returned %08x\n", ret);
2055     if(dsurface)
2056     {
2057         ret = IDirectDrawSurface_GetSurfaceDesc(dsurface, &desc);
2058         ok(ret == DD_OK, "GetSurfaceDesc returned %x\n", ret);
2059
2060         IDirectDrawSurface_Release(dsurface);
2061         dsurface = NULL;
2062
2063         ok(desc.dwFlags & DDSD_WIDTH, "Primary surface doesn't have width set\n");
2064         ok(desc.dwFlags & DDSD_HEIGHT, "Primary surface doesn't have height set\n");
2065         ok(desc.dwWidth == GetSystemMetrics(SM_CXSCREEN), "Surface width differs from screen width\n");
2066         ok(desc.dwHeight == GetSystemMetrics(SM_CYSCREEN), "Surface height differs from screen height\n");
2067     }
2068     ret = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
2069     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2070 }
2071
2072 START_TEST(dsurface)
2073 {
2074     if (!CreateDirectDraw())
2075         return;
2076     MipMapCreationTest();
2077     SrcColorKey32BlitTest();
2078     QueryInterface();
2079     GetDDInterface_1();
2080     GetDDInterface_2();
2081     GetDDInterface_4();
2082     GetDDInterface_7();
2083     EnumTest();
2084     AttachmentTest();
2085     AttachmentTest7();
2086     CubeMapTest();
2087     test_lockrect_invalid();
2088     CompressedTest();
2089     SizeTest();
2090     ReleaseDirectDraw();
2091 }