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