wined3d: read_from_framebuffer_texture() isn't suitable for readback of onscreen...
[wine/testsucceed.git] / dlls / ddraw / tests / dsurface.c
blobbfd5eaeab862e6226097ff896a2771dfe636fc79
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 /* Below we repeat the same test as above but now using BltFast instead of Blt. Before
308 * we can carry out the test we need to restore the color of the destination surface.
310 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
311 ok(rc==DD_OK,"Lock returned: %x\n",rc);
312 lpData = ddsd2.lpSurface;
313 lpData[0] = 0xCCCCCCCC;
314 lpData[1] = 0xCCCCCCCC;
315 lpData[2] = 0xCCCCCCCC;
316 lpData[3] = 0xCCCCCCCC;
317 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
318 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
320 IDirectDrawSurface_BltFast(lpDst, 0, 0, lpSrc, NULL, DDBLTFAST_SRCCOLORKEY);
322 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
323 ok(rc==DD_OK,"Lock returned: %x\n",rc);
324 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
325 lpData = ddsd2.lpSurface;
326 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
327 * color keying, but copy it to the destination surface. Others apply it for color keying, but
328 * do not copy it into the destination surface.
330 if(lpData[0]==0x00010203) {
331 trace("X channel was not copied into the destination surface\n");
332 ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
333 "Destination data after blitting is not correct\n");
334 } else {
335 ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
336 "Destination data after blitting is not correct\n");
338 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
339 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
341 /* Also test SetColorKey */
342 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
343 ok(DDColorKey.dwColorSpaceLowValue == 0xFF00FF && DDColorKey.dwColorSpaceHighValue == 0xFF00FF,
344 "GetColorKey does not return the colorkey used at surface creation\n");
346 DDColorKey.dwColorSpaceLowValue = 0x00FF00;
347 DDColorKey.dwColorSpaceHighValue = 0x00FF00;
348 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
350 DDColorKey.dwColorSpaceLowValue = 0;
351 DDColorKey.dwColorSpaceHighValue = 0;
352 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
353 ok(DDColorKey.dwColorSpaceLowValue == 0x00FF00 && DDColorKey.dwColorSpaceHighValue == 0x00FF00,
354 "GetColorKey does not return the colorkey set with SetColorKey\n");
356 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
357 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
358 IDirectDrawSurface_GetSurfaceDesc(lpSrc, &ddsd);
359 ok(ddsd.ddckCKSrcBlt.dwColorSpaceLowValue == 0x00FF00 && ddsd.ddckCKSrcBlt.dwColorSpaceHighValue == 0x00FF00,
360 "GetSurfaceDesc does not return the colorkey set with SetColorKey\n");
362 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
363 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
364 DDColorKey.dwColorSpaceHighValue = 0x000000;
365 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
367 DDColorKey.dwColorSpaceLowValue = 0;
368 DDColorKey.dwColorSpaceHighValue = 0;
369 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
370 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
371 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
373 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
374 DDColorKey.dwColorSpaceHighValue = 0x000001;
375 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
377 DDColorKey.dwColorSpaceLowValue = 0;
378 DDColorKey.dwColorSpaceHighValue = 0;
379 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
380 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
381 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
383 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
384 DDColorKey.dwColorSpaceHighValue = 0x0000FE;
385 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
387 DDColorKey.dwColorSpaceLowValue = 0;
388 DDColorKey.dwColorSpaceHighValue = 0;
389 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
390 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
391 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
393 IDirectDrawSurface_Release(lpSrc);
394 IDirectDrawSurface_Release(lpDst);
396 /* start with a new set of surfaces to test the color keying parameters to blit */
397 memset(&ddsd, 0, sizeof(ddsd));
398 ddsd.dwSize = sizeof(ddsd);
399 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
400 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
401 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
402 ddsd.dwWidth = 800;
403 ddsd.dwHeight = 600;
404 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
405 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
406 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
407 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
408 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
409 ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0xFF0000;
410 ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0xFF0000;
411 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x00FF00;
412 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x00FF00;
413 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
414 ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
415 if(FAILED(rc))
417 skip("Failed to create surface\n");
418 return;
421 /* start with a new set of surfaces to test the color keying parameters to blit */
422 memset(&ddsd, 0, sizeof(ddsd));
423 ddsd.dwSize = sizeof(ddsd);
424 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
425 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
426 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
427 ddsd.dwWidth = 800;
428 ddsd.dwHeight = 600;
429 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
430 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
431 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
432 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
433 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
434 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x0000FF;
435 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x0000FF;
436 ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0x000000;
437 ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0x000000;
438 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
439 ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
440 if(FAILED(rc))
442 skip("Failed to create surface\n");
443 IDirectDrawSurface_Release(lpDst);
444 return;
447 memset(&fx, 0, sizeof(fx));
448 fx.dwSize = sizeof(fx);
449 fx.ddckSrcColorkey.dwColorSpaceHighValue = 0x110000;
450 fx.ddckSrcColorkey.dwColorSpaceLowValue = 0x110000;
451 fx.ddckDestColorkey.dwColorSpaceHighValue = 0x001100;
452 fx.ddckDestColorkey.dwColorSpaceLowValue = 0x001100;
454 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
455 ok(rc==DD_OK,"Lock returned: %x\n",rc);
456 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
457 lpData = ddsd2.lpSurface;
458 lpData[0] = 0x000000FF; /* Applies to src blt key in src surface */
459 lpData[1] = 0x00000000; /* Applies to dst blt key in src surface */
460 lpData[2] = 0x00FF0000; /* Dst color key in dst surface */
461 lpData[3] = 0x0000FF00; /* Src color key in dst surface */
462 lpData[4] = 0x00001100; /* Src color key in ddbltfx */
463 lpData[5] = 0x00110000; /* Dst color key in ddbltfx */
464 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
465 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
467 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
468 ok(rc==DD_OK,"Lock returned: %x\n",rc);
469 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
470 lpData = ddsd2.lpSurface;
471 lpData[0] = 0x55555555;
472 lpData[1] = 0x55555555;
473 lpData[2] = 0x55555555;
474 lpData[3] = 0x55555555;
475 lpData[4] = 0x55555555;
476 lpData[5] = 0x55555555;
477 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
478 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
480 /* Test a blit without keying */
481 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, 0, &fx);
482 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
484 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
485 ok(rc==DD_OK,"Lock returned: %x\n",rc);
486 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
487 lpData = ddsd2.lpSurface;
488 /* Should have copied src data unmodified to dst */
489 ok(lpData[0] == 0x000000FF &&
490 lpData[1] == 0x00000000 &&
491 lpData[2] == 0x00FF0000 &&
492 lpData[3] == 0x0000FF00 &&
493 lpData[4] == 0x00001100 &&
494 lpData[5] == 0x00110000, "Surface data after unkeyed blit does not match\n");
496 lpData[0] = 0x55555555;
497 lpData[1] = 0x55555555;
498 lpData[2] = 0x55555555;
499 lpData[3] = 0x55555555;
500 lpData[4] = 0x55555555;
501 lpData[5] = 0x55555555;
502 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
503 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
505 /* Src key */
506 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
507 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
509 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
510 ok(rc==DD_OK,"Lock returned: %x\n",rc);
511 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
512 lpData = ddsd2.lpSurface;
514 ok(lpData[0] == 0x55555555 && /* Here the src key applied */
515 lpData[1] == 0x00000000 &&
516 lpData[2] == 0x00FF0000 &&
517 lpData[3] == 0x0000FF00 &&
518 lpData[4] == 0x00001100 &&
519 lpData[5] == 0x00110000, "Surface data after srckey blit does not match\n");
521 lpData[0] = 0x55555555;
522 lpData[1] = 0x55555555;
523 lpData[2] = 0x55555555;
524 lpData[3] = 0x55555555;
525 lpData[4] = 0x55555555;
526 lpData[5] = 0x55555555;
527 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
528 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
530 /* Src override */
531 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
532 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
534 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
535 ok(rc==DD_OK,"Lock returned: %x\n",rc);
536 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
537 lpData = ddsd2.lpSurface;
539 ok(lpData[0] == 0x000000FF &&
540 lpData[1] == 0x00000000 &&
541 lpData[2] == 0x00FF0000 &&
542 lpData[3] == 0x0000FF00 &&
543 lpData[4] == 0x00001100 &&
544 lpData[5] == 0x55555555, /* Override key applies here */
545 "Surface data after src override key blit does not match\n");
547 lpData[0] = 0x55555555;
548 lpData[1] = 0x55555555;
549 lpData[2] = 0x55555555;
550 lpData[3] = 0x55555555;
551 lpData[4] = 0x55555555;
552 lpData[5] = 0x55555555;
553 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
554 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
556 /* Src override AND src key. That is not supposed to work */
557 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &fx);
558 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
560 /* Verify that the destination is unchanged */
561 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
562 ok(rc==DD_OK,"Lock returned: %x\n",rc);
563 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
564 lpData = ddsd2.lpSurface;
566 ok(lpData[0] == 0x55555555 &&
567 lpData[1] == 0x55555555 &&
568 lpData[2] == 0x55555555 &&
569 lpData[3] == 0x55555555 &&
570 lpData[4] == 0x55555555 &&
571 lpData[5] == 0x55555555, /* Override key applies here */
572 "Surface data after src key blit with override does not match\n");
574 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
575 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
576 lpData[2] = 0x00001100; /* Dest key in override */
577 lpData[3] = 0x00001100; /* Dest key in override */
578 lpData[4] = 0x00000000; /* Dest key in src surface */
579 lpData[5] = 0x00000000; /* Dest key in src surface */
580 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
581 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
583 /* Dest key blit */
584 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
585 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
587 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
588 ok(rc==DD_OK,"Lock returned: %x\n",rc);
589 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
590 lpData = ddsd2.lpSurface;
592 /* DirectDraw uses the dest blit key from the SOURCE surface ! */
593 ok(lpData[0] == 0x00ff0000 &&
594 lpData[1] == 0x00ff0000 &&
595 lpData[2] == 0x00001100 &&
596 lpData[3] == 0x00001100 &&
597 lpData[4] == 0x00001100 && /* Key applies here */
598 lpData[5] == 0x00110000, /* Key applies here */
599 "Surface data after dest key blit does not match\n");
601 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
602 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
603 lpData[2] = 0x00001100; /* Dest key in override */
604 lpData[3] = 0x00001100; /* Dest key in override */
605 lpData[4] = 0x00000000; /* Dest key in src surface */
606 lpData[5] = 0x00000000; /* Dest key in src surface */
607 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
608 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
610 /* Dest override key blit */
611 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
612 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
614 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
615 ok(rc==DD_OK,"Lock returned: %x\n",rc);
616 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
617 lpData = ddsd2.lpSurface;
619 ok(lpData[0] == 0x00FF0000 &&
620 lpData[1] == 0x00FF0000 &&
621 lpData[2] == 0x00FF0000 && /* Key applies here */
622 lpData[3] == 0x0000FF00 && /* Key applies here */
623 lpData[4] == 0x00000000 &&
624 lpData[5] == 0x00000000,
625 "Surface data after dest key override blit does not match\n");
627 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
628 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
629 lpData[2] = 0x00001100; /* Dest key in override */
630 lpData[3] = 0x00001100; /* Dest key in override */
631 lpData[4] = 0x00000000; /* Dest key in src surface */
632 lpData[5] = 0x00000000; /* Dest key in src surface */
633 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
634 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
636 /* Dest override key blit. Supposed to fail too */
637 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYDESTOVERRIDE, &fx);
638 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
640 /* Check for unchanged data */
641 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
642 ok(rc==DD_OK,"Lock returned: %x\n",rc);
643 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
644 lpData = ddsd2.lpSurface;
646 ok(lpData[0] == 0x00FF0000 &&
647 lpData[1] == 0x00FF0000 &&
648 lpData[2] == 0x00001100 && /* Key applies here */
649 lpData[3] == 0x00001100 && /* Key applies here */
650 lpData[4] == 0x00000000 &&
651 lpData[5] == 0x00000000,
652 "Surface data with dest key and dest override does not match\n");
654 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
655 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
656 lpData[2] = 0x00001100; /* Dest key in override */
657 lpData[3] = 0x00001100; /* Dest key in override */
658 lpData[4] = 0x00000000; /* Dest key in src surface */
659 lpData[5] = 0x00000000; /* Dest key in src surface */
660 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
661 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
663 /* Modify the source data a bit to give some more conclusive results */
664 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
665 ok(rc==DD_OK,"Lock returned: %x\n",rc);
666 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
667 lpData = ddsd2.lpSurface;
668 lpData[5] = 0x000000FF; /* Applies to src blt key in src surface */
669 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
670 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
672 /* Source and destination key */
673 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYSRC, &fx);
674 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
676 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
677 ok(rc==DD_OK,"Lock returned: %x\n",rc);
678 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
679 lpData = ddsd2.lpSurface;
681 ok(lpData[0] == 0x00FF0000 && /* Masked by Destination key */
682 lpData[1] == 0x00FF0000 && /* Masked by Destination key */
683 lpData[2] == 0x00001100 && /* Masked by Destination key */
684 lpData[3] == 0x00001100 && /* Masked by Destination key */
685 lpData[4] == 0x00001100 && /* Allowed by destination key, not masked by source key */
686 lpData[5] == 0x00000000, /* Allowed by dst key, but masked by source key */
687 "Surface data with src key and dest key blit does not match\n");
689 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
690 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
691 lpData[2] = 0x00001100; /* Dest key in override */
692 lpData[3] = 0x00001100; /* Dest key in override */
693 lpData[4] = 0x00000000; /* Dest key in src surface */
694 lpData[5] = 0x00000000; /* Dest key in src surface */
695 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
696 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
698 /* Override keys without ddbltfx parameter fail */
699 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, NULL);
700 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
701 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, NULL);
702 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
704 /* Try blitting without keys in the source surface*/
705 rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, NULL);
706 ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
707 rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_DESTBLT, NULL);
708 ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
710 /* That fails now. Do not bother to check that the data is unmodified */
711 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
712 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
714 /* Dest key blit still works. Which key is used this time??? */
715 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
716 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
718 /* With correctly passed override keys no key in the surface is needed.
719 * Again, the result was checked before, no need to do that again
721 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
722 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
723 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
724 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
726 IDirectDrawSurface_Release(lpSrc);
727 IDirectDrawSurface_Release(lpDst);
730 static void QueryInterface(void)
732 LPDIRECTDRAWSURFACE dsurface;
733 DDSURFACEDESC surface;
734 LPVOID object;
735 HRESULT ret;
737 /* Create a surface */
738 ZeroMemory(&surface, sizeof(surface));
739 surface.dwSize = sizeof(surface);
740 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
741 surface.dwHeight = 10;
742 surface.dwWidth = 10;
743 ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
744 if(ret != DD_OK)
746 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
747 return;
750 /* Call IUnknown::QueryInterface */
751 ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
752 ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %x\n", ret);
754 IDirectDrawSurface_Release(dsurface);
757 /* The following tests test which interface is returned by IDirectDrawSurfaceX::GetDDInterface.
758 * It uses refcounts to test that and compares the interface addresses. Partially fits here, and
759 * partially in the refcount test
762 static ULONG getref(IUnknown *iface)
764 IUnknown_AddRef(iface);
765 return IUnknown_Release(iface);
768 static void GetDDInterface_1(void)
770 LPDIRECTDRAWSURFACE dsurface;
771 LPDIRECTDRAWSURFACE2 dsurface2;
772 DDSURFACEDESC surface;
773 HRESULT ret;
774 IDirectDraw2 *dd2;
775 IDirectDraw4 *dd4;
776 IDirectDraw7 *dd7;
777 ULONG ref1, ref2, ref4, ref7;
778 void *dd;
780 /* Create a surface */
781 ZeroMemory(&surface, sizeof(surface));
782 surface.dwSize = sizeof(surface);
783 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
784 surface.dwHeight = 10;
785 surface.dwWidth = 10;
786 ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
787 if(ret != DD_OK)
789 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
790 return;
792 ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
793 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
794 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
795 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
796 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
797 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
798 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
799 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
801 ref1 = getref((IUnknown *) lpDD);
802 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
803 ref2 = getref((IUnknown *) dd2);
804 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
805 ref4 = getref((IUnknown *) dd4);
806 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
807 ref7 = getref((IUnknown *) dd7);
808 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
811 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
812 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
813 ok(getref((IUnknown *) lpDD) == ref1 + 1, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
814 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
815 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
816 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
818 ok(dd == lpDD, "Returned interface pointer is not equal to the creation interface\n");
819 IUnknown_Release((IUnknown *) dd);
821 /* try a NULL pointer */
822 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, NULL);
823 ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
825 IDirectDraw_Release(dd2);
826 IDirectDraw_Release(dd4);
827 IDirectDraw_Release(dd7);
828 IDirectDrawSurface2_Release(dsurface2);
829 IDirectDrawSurface_Release(dsurface);
832 static void GetDDInterface_2(void)
834 LPDIRECTDRAWSURFACE dsurface;
835 LPDIRECTDRAWSURFACE2 dsurface2;
836 DDSURFACEDESC surface;
837 HRESULT ret;
838 IDirectDraw2 *dd2;
839 IDirectDraw4 *dd4;
840 IDirectDraw7 *dd7;
841 ULONG ref1, ref2, ref4, ref7;
842 void *dd;
844 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
845 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
846 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
847 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
848 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
849 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
851 /* Create a surface */
852 ZeroMemory(&surface, sizeof(surface));
853 surface.dwSize = sizeof(surface);
854 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
855 surface.dwHeight = 10;
856 surface.dwWidth = 10;
857 ret = IDirectDraw2_CreateSurface(dd2, &surface, &dsurface, NULL);
858 if(ret != DD_OK)
860 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
861 return;
863 ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
864 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
866 ref1 = getref((IUnknown *) lpDD);
867 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
868 ref2 = getref((IUnknown *) dd2);
869 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
870 ref4 = getref((IUnknown *) dd4);
871 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
872 ref7 = getref((IUnknown *) dd7);
873 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
876 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
877 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
878 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
879 ok(getref((IUnknown *) dd2) == ref2 + 1, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
880 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
881 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
883 ok(dd == dd2, "Returned interface pointer is not equal to the creation interface\n");
884 IUnknown_Release((IUnknown *) dd);
886 IDirectDraw_Release(dd2);
887 IDirectDraw_Release(dd4);
888 IDirectDraw_Release(dd7);
889 IDirectDrawSurface2_Release(dsurface2);
890 IDirectDrawSurface_Release(dsurface);
893 static void GetDDInterface_4(void)
895 LPDIRECTDRAWSURFACE2 dsurface2;
896 LPDIRECTDRAWSURFACE4 dsurface4;
897 DDSURFACEDESC2 surface;
898 HRESULT ret;
899 IDirectDraw2 *dd2;
900 IDirectDraw4 *dd4;
901 IDirectDraw7 *dd7;
902 ULONG ref1, ref2, ref4, ref7;
903 void *dd;
905 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
906 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
907 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
908 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
909 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
910 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
912 /* Create a surface */
913 ZeroMemory(&surface, sizeof(surface));
914 surface.dwSize = sizeof(surface);
915 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
916 surface.dwHeight = 10;
917 surface.dwWidth = 10;
918 ret = IDirectDraw4_CreateSurface(dd4, &surface, &dsurface4, NULL);
919 if(ret != DD_OK)
921 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
922 return;
924 ret = IDirectDrawSurface4_QueryInterface(dsurface4, &IID_IDirectDrawSurface2, (void **) &dsurface2);
925 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
927 ref1 = getref((IUnknown *) lpDD);
928 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
929 ref2 = getref((IUnknown *) dd2);
930 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
931 ref4 = getref((IUnknown *) dd4);
932 ok(ref4 == 2, "IDirectDraw4 refcount is %d\n", ref4);
933 ref7 = getref((IUnknown *) dd7);
934 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
936 ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
937 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
938 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
939 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
940 ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
941 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
943 ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
944 IUnknown_Release((IUnknown *) dd);
946 /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
947 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
948 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
949 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
950 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
951 ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
952 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
954 ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
955 IUnknown_Release((IUnknown *) dd);
957 IDirectDraw_Release(dd2);
958 IDirectDraw_Release(dd4);
959 IDirectDraw_Release(dd7);
960 IDirectDrawSurface4_Release(dsurface4);
961 IDirectDrawSurface2_Release(dsurface2);
964 static void GetDDInterface_7(void)
966 LPDIRECTDRAWSURFACE4 dsurface4;
967 LPDIRECTDRAWSURFACE7 dsurface7;
968 DDSURFACEDESC2 surface;
969 HRESULT ret;
970 IDirectDraw2 *dd2;
971 IDirectDraw4 *dd4;
972 IDirectDraw7 *dd7;
973 ULONG ref1, ref2, ref4, ref7;
974 void *dd;
976 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
977 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
978 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
979 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
980 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
981 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
983 /* Create a surface */
984 ZeroMemory(&surface, sizeof(surface));
985 surface.dwSize = sizeof(surface);
986 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
987 surface.dwHeight = 10;
988 surface.dwWidth = 10;
989 ret = IDirectDraw7_CreateSurface(dd7, &surface, &dsurface7, NULL);
990 if(ret != DD_OK)
992 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
993 return;
995 ret = IDirectDrawSurface7_QueryInterface(dsurface7, &IID_IDirectDrawSurface4, (void **) &dsurface4);
996 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
998 ref1 = getref((IUnknown *) lpDD);
999 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
1000 ref2 = getref((IUnknown *) dd2);
1001 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
1002 ref4 = getref((IUnknown *) dd4);
1003 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
1004 ref7 = getref((IUnknown *) dd7);
1005 ok(ref7 == 2, "IDirectDraw7 refcount is %d\n", ref7);
1007 ret = IDirectDrawSurface7_GetDDInterface(dsurface7, &dd);
1008 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1009 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1010 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1011 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1012 ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1014 ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1015 IUnknown_Release((IUnknown *) dd);
1017 /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
1018 ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
1019 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1020 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1021 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1022 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1023 ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1025 ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1026 IUnknown_Release((IUnknown *) dd);
1028 IDirectDraw_Release(dd2);
1029 IDirectDraw_Release(dd4);
1030 IDirectDraw_Release(dd7);
1031 IDirectDrawSurface4_Release(dsurface4);
1032 IDirectDrawSurface7_Release(dsurface7);
1035 static ULONG getRefcount(IUnknown *iface)
1037 IUnknown_AddRef(iface);
1038 return IUnknown_Release(iface);
1041 static void IFaceRefCount(void)
1043 LPDIRECTDRAWSURFACE surf;
1044 DDSURFACEDESC surface;
1045 HRESULT ret;
1046 IDirectDrawSurface2 *surf2;
1047 IDirectDrawSurface2 *surf2a;
1048 IDirectDrawSurface4 *surf4;
1049 IDirectDrawSurface7 *surf7a;
1050 IDirectDrawSurface7 *surf7b;
1051 IDirect3DTexture* tex;
1052 IDirect3DTexture2* tex2;
1053 IDirectDrawGammaControl* gamma;
1054 ULONG ref;
1056 /* Create a surface */
1057 ZeroMemory(&surface, sizeof(surface));
1058 surface.dwSize = sizeof(surface);
1059 surface.dwFlags = DDSD_CAPS;
1060 surface.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1061 ret = IDirectDraw_CreateSurface(lpDD, &surface, &surf, NULL);
1063 if (ret != DD_OK)
1065 ok(FALSE, "Could not create surface, skipping test\n");
1066 return;
1069 ref = getRefcount((IUnknown *) surf);
1070 ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
1072 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
1073 ref = getRefcount((IUnknown *) surf);
1074 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
1075 ref = getRefcount((IUnknown *) surf2);
1076 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* This should also be one */
1078 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2a);
1079 ref = getRefcount((IUnknown *) surf2);
1080 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref); /* Surf2's refcount should be 2 now, but surf should be 1 */
1081 ref = getRefcount((IUnknown *) surf);
1082 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1084 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface4, (void **) &surf4);
1085 ref = getRefcount((IUnknown *) surf4);
1086 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1088 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7a);
1089 ref = getRefcount((IUnknown *) surf7a);
1090 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1092 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7b);
1093 ref = getRefcount((IUnknown *) surf7b);
1094 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1096 /* IDirect3DTexture interface (unlike the others) alters the original IDirectDrawSurface ref count */
1097 ret = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture, (void **) &tex);
1098 if (SUCCEEDED(ret))
1100 ref = getRefcount((IUnknown *) tex);
1101 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1102 ref = getRefcount((IUnknown *) surf);
1103 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1105 IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture2, (void **) &tex2);
1106 ref = getRefcount((IUnknown *) tex);
1107 todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1108 ref = getRefcount((IUnknown *) tex2);
1109 todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1110 ref = getRefcount((IUnknown *) surf);
1111 todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1113 IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawGammaControl, (void **) &gamma);
1114 ref = getRefcount((IUnknown *) gamma);
1115 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1117 ref = IDirect3DTexture2_Release(tex2); /* Release the texture */
1118 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1119 ref = getRefcount((IUnknown *) surf);
1120 todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1122 ref = IDirect3DTexture_Release(tex); /* Release the texture */
1123 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1124 ref = getRefcount((IUnknown *) surf);
1125 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1127 ref = IDirectDrawGammaControl_Release(gamma); /* Release the gamma control */
1128 todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1131 ref = IDirectDrawSurface2_Release(surf2); /* Release one of the 2 surf2 interfaces */
1132 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1134 ref = IDirectDrawSurface2_Release(surf2a); /* Release the other */
1135 todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1137 ref = IDirectDrawSurface4_Release(surf4);
1138 todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1140 ref = IDirectDrawSurface7_Release(surf7a);
1141 todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1143 ref = IDirectDrawSurface7_Release(surf7b);
1144 todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1146 ref = IDirectDrawSurface_Release(surf);
1147 ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1150 #define MAXEXPECTED 8 /* Can match up to 8 expected surfaces */
1151 struct enumstruct
1153 IDirectDrawSurface *expected[MAXEXPECTED];
1154 UINT count;
1157 static HRESULT WINAPI enumCB(IDirectDrawSurface *surf, DDSURFACEDESC *desc, void *ctx)
1159 int i;
1160 BOOL found = FALSE;
1162 for(i = 0; i < MAXEXPECTED; i++)
1164 if(((struct enumstruct *)ctx)->expected[i] == surf) found = TRUE;
1167 ok(found, "Unexpected surface %p enumerated\n", surf);
1168 ((struct enumstruct *)ctx)->count++;
1169 IDirectDrawSurface_Release(surf);
1170 return DDENUMRET_OK;
1173 static void EnumTest(void)
1175 HRESULT rc;
1176 DDSURFACEDESC ddsd;
1177 IDirectDrawSurface *surface;
1178 struct enumstruct ctx;
1180 ddsd.dwSize = sizeof(ddsd);
1181 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1182 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1183 U2(ddsd).dwMipMapCount = 3;
1184 ddsd.dwWidth = 32;
1185 ddsd.dwHeight = 32;
1186 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
1187 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
1189 memset(&ctx, 0, sizeof(ctx));
1190 ctx.expected[0] = surface;
1191 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[0], &ddsd.ddsCaps, &ctx.expected[1]);
1192 ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1193 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[1], &ddsd.ddsCaps, &ctx.expected[2]);
1194 ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1195 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[2], &ddsd.ddsCaps, &ctx.expected[3]);
1196 ok(rc == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", rc);
1197 ok(!ctx.expected[3], "expected NULL pointer\n");
1198 ctx.count = 0;
1200 rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, &ddsd, &ctx, enumCB);
1201 ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
1202 ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
1204 IDirectDrawSurface_Release(ctx.expected[2]);
1205 IDirectDrawSurface_Release(ctx.expected[1]);
1206 IDirectDrawSurface_Release(surface);
1209 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1211 UINT *num = context;
1212 (*num)++;
1213 IDirectDrawSurface_Release(surface);
1214 return DDENUMRET_OK;
1217 static void AttachmentTest7(void)
1219 HRESULT hr;
1220 IDirectDraw7 *dd7;
1221 IDirectDrawSurface7 *surface1, *surface2, *surface3, *surface4;
1222 DDSURFACEDESC2 ddsd, ddsd2;
1223 UINT num;
1224 DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0}, caps2 = {DDSCAPS_BACKBUFFER,0,0,0};
1225 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1227 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1228 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1230 memset(&ddsd, 0, sizeof(ddsd));
1231 ddsd.dwSize = sizeof(ddsd);
1232 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1233 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1234 U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1235 ddsd.dwWidth = 128;
1236 ddsd.dwHeight = 128;
1237 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1238 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1240 /* ROOT */
1241 num = 0;
1242 IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1243 ok(num == 1, "Mipmap root has %d surfaces attached, expected 1\n", num);
1244 /* DONE ROOT */
1246 /* LEVEL 1 */
1247 hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1248 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1249 num = 0;
1250 IDirectDrawSurface7_EnumAttachedSurfaces(surface2, &num, SurfaceCounter);
1251 ok(num == 1, "First mip level has %d surfaces attached, expected 1\n", num);
1252 /* DONE LEVEL 1 */
1254 /* LEVEL 2 */
1255 hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1256 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1257 IDirectDrawSurface7_Release(surface2);
1258 num = 0;
1259 IDirectDrawSurface7_EnumAttachedSurfaces(surface3, &num, SurfaceCounter);
1260 ok(num == 0, "Second mip level has %d surfaces attached, expected 1\n", num);
1261 /* Done level 2 */
1262 /* Mip level 3 is still needed */
1263 hr = IDirectDrawSurface7_GetAttachedSurface(surface3, &caps, &surface4);
1264 ok(hr == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", hr);
1265 ok(!surface4, "expected NULL pointer\n");
1267 /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1268 memset(&ddsd, 0, sizeof(ddsd));
1269 ddsd.dwSize = sizeof(ddsd);
1270 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1271 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1272 ddsd.dwWidth = 16;
1273 ddsd.dwHeight = 16;
1274 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1275 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1277 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1278 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1279 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1280 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1281 hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1282 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1283 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1284 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1286 IDirectDrawSurface7_Release(surface2);
1288 memset(&ddsd, 0, sizeof(ddsd));
1289 ddsd.dwSize = sizeof(ddsd);
1290 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1291 ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1292 ddsd.dwWidth = 16;
1293 ddsd.dwHeight = 16;
1294 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1295 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1297 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1298 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1299 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1300 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1301 hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1302 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1303 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1304 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1306 IDirectDrawSurface7_Release(surface3);
1307 IDirectDrawSurface7_Release(surface2);
1308 IDirectDrawSurface7_Release(surface1);
1310 hr = IDirectDraw7_SetCooperativeLevel(dd7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1311 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1313 memset(&ddsd, 0, sizeof(ddsd));
1314 ddsd.dwSize = sizeof(ddsd);
1315 ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
1316 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
1317 ddsd.dwBackBufferCount = 2;
1318 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1319 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1321 /* backbuffer surfaces must not have dwBackBufferCount set */
1322 ddsd2.dwSize = sizeof(ddsd2);
1323 hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps2, &surface2);
1324 ok(hr==DD_OK,"GetAttachedSurface returned: %x\n", hr);
1325 hr = IDirectDrawSurface7_GetSurfaceDesc(surface2, &ddsd2);
1326 ok(hr==DD_OK,"GetSurfaceDesc returned: %x\n", hr);
1327 ok(ddsd2.dwBackBufferCount==0,"backbuffer surface has dwBackBufferCount==%u\n", ddsd2.dwBackBufferCount);
1329 num = 0;
1330 IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1331 ok(num == 1, "Primary surface has %d surfaces attached, expected 1\n", num);
1332 IDirectDrawSurface7_Release(surface1);
1334 /* Those are some invalid descriptions, no need to test attachments with them */
1335 memset(&ddsd, 0, sizeof(ddsd));
1336 ddsd.dwSize = sizeof(ddsd);
1337 ddsd.dwFlags = DDSD_CAPS;
1338 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1339 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1340 ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1341 memset(&ddsd, 0, sizeof(ddsd));
1342 ddsd.dwSize = sizeof(ddsd);
1343 ddsd.dwFlags = DDSD_CAPS;
1344 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1345 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1346 ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1348 /* Try a single primary and two offscreen plain surfaces */
1349 memset(&ddsd, 0, sizeof(ddsd));
1350 ddsd.dwSize = sizeof(ddsd);
1351 ddsd.dwFlags = DDSD_CAPS;
1352 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1353 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1354 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1356 memset(&ddsd, 0, sizeof(ddsd));
1357 ddsd.dwSize = sizeof(ddsd);
1358 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1359 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1360 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1361 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1362 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1363 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1365 memset(&ddsd, 0, sizeof(ddsd));
1366 ddsd.dwSize = sizeof(ddsd);
1367 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1368 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1369 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1370 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1371 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface3, NULL);
1372 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1374 /* This one has a different size */
1375 memset(&ddsd, 0, sizeof(ddsd));
1376 ddsd.dwSize = sizeof(ddsd);
1377 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1378 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1379 ddsd.dwWidth = 128;
1380 ddsd.dwHeight = 128;
1381 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface4, NULL);
1382 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1384 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1385 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1386 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1387 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1388 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1389 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1390 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1391 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1392 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1393 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1395 IDirectDrawSurface7_Release(surface4);
1396 IDirectDrawSurface7_Release(surface3);
1397 IDirectDrawSurface7_Release(surface2);
1398 IDirectDrawSurface7_Release(surface1);
1400 hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL);
1401 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1402 IDirectDraw7_Release(dd7);
1405 static void AttachmentTest(void)
1407 HRESULT hr;
1408 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
1409 DDSURFACEDESC ddsd;
1410 DDSCAPS caps = {DDSCAPS_TEXTURE};
1411 BOOL refrast = FALSE;
1412 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1414 memset(&ddsd, 0, sizeof(ddsd));
1415 ddsd.dwSize = sizeof(ddsd);
1416 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1417 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1418 U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1419 ddsd.dwWidth = 128;
1420 ddsd.dwHeight = 128;
1421 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1422 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1424 hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1425 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1426 hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1427 ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1429 /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1430 memset(&ddsd, 0, sizeof(ddsd));
1431 ddsd.dwSize = sizeof(ddsd);
1432 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1433 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1434 ddsd.dwWidth = 16;
1435 ddsd.dwHeight = 16;
1436 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1437 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1439 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1440 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1441 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1442 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1443 hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
1444 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1445 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1446 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1447 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
1448 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 64x64 texture sublevel returned %08x\n", hr);
1449 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1450 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 texture returned %08x\n", hr);
1452 IDirectDrawSurface7_Release(surface4);
1454 memset(&ddsd, 0, sizeof(ddsd));
1455 ddsd.dwSize = sizeof(ddsd);
1456 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1457 ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1458 ddsd.dwWidth = 16;
1459 ddsd.dwHeight = 16;
1460 hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1461 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1463 if (SUCCEEDED(IDirectDrawSurface7_AddAttachedSurface(surface1, surface4)))
1465 IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1466 refrast = TRUE;
1469 hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4); /* Succeeds on refrast */
1470 if (refrast)
1471 ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1472 else
1473 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1474 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1476 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1); /* Succeeds on refrast */
1477 if (refrast)
1478 ok(hr == S_OK, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1479 else
1480 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1481 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface1);
1483 hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4); /* Succeeds on refrast */
1484 if (refrast)
1485 ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1486 else
1487 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1488 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface3, 0, surface4);
1490 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1491 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1492 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface3);
1494 hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4); /* Succeeds on refrast */
1495 if (refrast)
1496 ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1497 else
1498 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1499 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface2, 0, surface4);
1501 hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1502 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 offscreen plain surface returned %08x\n", hr);
1503 if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface2);
1505 IDirectDrawSurface7_Release(surface4);
1506 IDirectDrawSurface7_Release(surface3);
1507 IDirectDrawSurface7_Release(surface2);
1508 IDirectDrawSurface7_Release(surface1);
1510 hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1511 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1513 /* Creating a back buffer as-is, is not allowed. No need to perform attachment tests */
1514 memset(&ddsd, 0, sizeof(ddsd));
1515 ddsd.dwSize = sizeof(ddsd);
1516 ddsd.dwFlags = DDSD_CAPS;
1517 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1518 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1519 ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1520 /* This old ddraw version happily creates explicit front buffers */
1521 memset(&ddsd, 0, sizeof(ddsd));
1522 ddsd.dwSize = sizeof(ddsd);
1523 ddsd.dwFlags = DDSD_CAPS;
1524 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1525 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1526 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1527 IDirectDrawSurface_Release(surface1);
1529 /* Try a single primary and two offscreen plain surfaces */
1530 memset(&ddsd, 0, sizeof(ddsd));
1531 ddsd.dwSize = sizeof(ddsd);
1532 ddsd.dwFlags = DDSD_CAPS;
1533 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1534 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1535 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1537 memset(&ddsd, 0, sizeof(ddsd));
1538 ddsd.dwSize = sizeof(ddsd);
1539 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1540 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1541 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1542 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1543 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1544 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1546 memset(&ddsd, 0, sizeof(ddsd));
1547 ddsd.dwSize = sizeof(ddsd);
1548 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1549 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1550 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1551 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1552 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
1553 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1555 /* This one has a different size */
1556 memset(&ddsd, 0, sizeof(ddsd));
1557 ddsd.dwSize = sizeof(ddsd);
1558 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1559 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1560 ddsd.dwWidth = 128;
1561 ddsd.dwHeight = 128;
1562 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1563 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1565 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
1566 ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1567 "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1568 if(SUCCEEDED(hr))
1570 /* Try the reverse without detaching first */
1571 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1572 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
1573 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1574 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1576 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1577 ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1578 "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1579 if(SUCCEEDED(hr))
1581 /* Try to detach reversed */
1582 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1583 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
1584 /* Now the proper detach */
1585 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
1586 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1588 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3); /* Fails on refrast */
1589 ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1590 "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1591 if(SUCCEEDED(hr))
1593 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
1594 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1596 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
1597 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1598 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
1599 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1601 IDirectDrawSurface_Release(surface4);
1602 IDirectDrawSurface_Release(surface3);
1603 IDirectDrawSurface_Release(surface2);
1604 IDirectDrawSurface_Release(surface1);
1606 hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
1607 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1609 DestroyWindow(window);
1612 struct compare
1614 DWORD width, height;
1615 DWORD caps, caps2;
1616 UINT mips;
1619 static HRESULT WINAPI CubeTestLvl2Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1621 UINT *mips = context;
1623 (*mips)++;
1624 IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1625 context,
1626 CubeTestLvl2Enum);
1628 return DDENUMRET_OK;
1631 static HRESULT WINAPI CubeTestLvl1Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1633 UINT mips = 0;
1634 UINT *num = context;
1635 static const struct compare expected[] =
1638 128, 128,
1639 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1640 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ,
1644 128, 128,
1645 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1646 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ,
1650 128, 128,
1651 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1652 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY,
1656 128, 128,
1657 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1658 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY,
1662 128, 128,
1663 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1664 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX,
1668 64, 64, /* This is the first mipmap */
1669 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1670 DDSCAPS2_MIPMAPSUBLEVEL | DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX,
1675 mips = 0;
1676 IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1677 &mips,
1678 CubeTestLvl2Enum);
1680 ok(desc->dwWidth == expected[*num].width, "Surface width is %d expected %d\n", desc->dwWidth, expected[*num].width);
1681 ok(desc->dwHeight == expected[*num].height, "Surface height is %d expected %d\n", desc->dwHeight, expected[*num].height);
1682 ok(desc->ddsCaps.dwCaps == expected[*num].caps, "Surface caps are %08x expected %08x\n", desc->ddsCaps.dwCaps, expected[*num].caps);
1683 ok(desc->ddsCaps.dwCaps2 == expected[*num].caps2, "Surface caps2 are %08x expected %08x\n", desc->ddsCaps.dwCaps2, expected[*num].caps2);
1684 ok(mips == expected[*num].mips, "Surface has %d mipmaps, expected %d\n", mips, expected[*num].mips);
1686 (*num)++;
1688 IDirectDrawSurface7_Release(surface);
1690 return DDENUMRET_OK;
1693 static void CubeMapTest(void)
1695 IDirectDraw7 *dd7 = NULL;
1696 IDirectDrawSurface7 *cubemap = NULL;
1697 DDSURFACEDESC2 ddsd;
1698 HRESULT hr;
1699 UINT num = 0;
1700 struct enumstruct ctx;
1702 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1703 ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1704 if (FAILED(hr)) goto err;
1706 memset(&ddsd, 0, sizeof(ddsd));
1707 ddsd.dwSize = sizeof(ddsd);
1708 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1709 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1710 ddsd.dwWidth = 128;
1711 ddsd.dwHeight = 128;
1712 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1713 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1715 /* D3DFMT_R5G6B5 */
1716 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1717 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1718 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1719 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1720 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1722 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1723 if (FAILED(hr))
1725 skip("Can't create cubemap surface\n");
1726 goto err;
1729 hr = IDirectDrawSurface7_GetSurfaceDesc(cubemap, &ddsd);
1730 ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
1731 ok(ddsd.ddsCaps.dwCaps == (DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX),
1732 "Root Caps are %08x\n", ddsd.ddsCaps.dwCaps);
1733 ok(ddsd.ddsCaps.dwCaps2 == (DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP),
1734 "Root Caps2 are %08x\n", ddsd.ddsCaps.dwCaps2);
1736 IDirectDrawSurface7_EnumAttachedSurfaces(cubemap,
1737 &num,
1738 CubeTestLvl1Enum);
1739 ok(num == 6, "Surface has %d attachments\n", num);
1740 IDirectDrawSurface7_Release(cubemap);
1742 /* What happens if I do not specify any faces? */
1743 memset(&ddsd, 0, sizeof(ddsd));
1744 ddsd.dwSize = sizeof(ddsd);
1745 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1746 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1747 ddsd.dwWidth = 128;
1748 ddsd.dwHeight = 128;
1749 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1750 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP;
1752 /* D3DFMT_R5G6B5 */
1753 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1754 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1755 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1756 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1757 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1759 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1760 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7::CreateSurface asking for a cube map without faces returned %08x\n", hr);
1762 /* Cube map faces without a cube map? */
1763 memset(&ddsd, 0, sizeof(ddsd));
1764 ddsd.dwSize = sizeof(ddsd);
1765 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1766 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1767 ddsd.dwWidth = 128;
1768 ddsd.dwHeight = 128;
1769 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1770 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_ALLFACES;
1772 /* D3DFMT_R5G6B5 */
1773 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1774 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1775 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1776 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1777 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1779 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1780 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1782 memset(&ddsd, 0, sizeof(ddsd));
1783 ddsd.dwSize = sizeof(ddsd);
1784 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1785 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1786 ddsd.dwWidth = 128;
1787 ddsd.dwHeight = 128;
1788 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1789 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEX;
1791 /* D3DFMT_R5G6B5 */
1792 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1793 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1794 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1795 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1796 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1798 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1799 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1801 /* Make sure everything is cleaned up properly. Use the enumSurfaces test infrastructure */
1802 memset(&ctx, 0, sizeof(ctx));
1803 memset(&ddsd, 0, sizeof(ddsd));
1804 ddsd.dwSize = sizeof(DDSURFACEDESC);
1805 hr = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, (DDSURFACEDESC *) &ddsd, (void *) &ctx, enumCB);
1806 ok(hr == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", hr);
1807 ok(ctx.count == 0, "%d surfaces enumerated, expected 0\n", ctx.count);
1809 err:
1810 if (dd7) IDirectDraw7_Release(dd7);
1813 static void test_lockrect_invalid(void)
1815 unsigned int i, j;
1817 RECT valid[] = {
1818 {60, 60, 68, 68},
1819 {60, 60, 60, 68},
1820 {60, 60, 68, 60},
1821 {120, 60, 128, 68},
1822 {60, 120, 68, 128},
1825 RECT invalid[] = {
1826 {68, 60, 60, 68}, /* left > right */
1827 {60, 68, 68, 60}, /* top > bottom */
1828 {-8, 60, 0, 68}, /* left < surface */
1829 {60, -8, 68, 0}, /* top < surface */
1830 {-16, 60, -8, 68}, /* right < surface */
1831 {60, -16, 68, -8}, /* bottom < surface */
1832 {60, 60, 136, 68}, /* right > surface */
1833 {60, 60, 68, 136}, /* bottom > surface */
1834 {136, 60, 144, 68}, /* left > surface */
1835 {60, 136, 68, 144}, /* top > surface */
1838 const DWORD dds_caps[] = {
1839 DDSCAPS_OFFSCREENPLAIN
1842 for (j = 0; j < (sizeof(dds_caps) / sizeof(*dds_caps)); ++j)
1844 IDirectDrawSurface *surface = 0;
1845 DDSURFACEDESC surface_desc = {0};
1846 DDSURFACEDESC locked_desc = {0};
1847 HRESULT hr;
1849 surface_desc.dwSize = sizeof(surface_desc);
1850 surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
1851 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1852 surface_desc.ddsCaps.dwCaps = dds_caps[j];
1853 surface_desc.dwWidth = 128;
1854 surface_desc.dwHeight = 128;
1855 surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
1856 U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
1857 U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xFF0000;
1858 U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00FF00;
1859 U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000FF;
1861 hr = IDirectDraw_CreateSurface(lpDD, &surface_desc, &surface, NULL);
1862 ok(SUCCEEDED(hr), "CreateSurface failed (0x%08x)\n", hr);
1863 if (FAILED(hr)) {
1864 skip("failed to create surface\n");
1865 continue;
1868 for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i)
1870 RECT *rect = &valid[i];
1872 memset(&locked_desc, 0, sizeof(locked_desc));
1873 locked_desc.dwSize = sizeof(locked_desc);
1875 hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1876 ok(SUCCEEDED(hr), "Lock failed (0x%08x) for rect [%d, %d]->[%d, %d]\n",
1877 hr, rect->left, rect->top, rect->right, rect->bottom);
1879 hr = IDirectDrawSurface_Unlock(surface, NULL);
1880 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1883 for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i)
1885 RECT *rect = &invalid[i];
1887 memset(&locked_desc, 1, sizeof(locked_desc));
1888 locked_desc.dwSize = sizeof(locked_desc);
1890 hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1891 ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for rect [%d, %d]->[%d, %d]"
1892 ", expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, rect->left, rect->top,
1893 rect->right, rect->bottom, DDERR_INVALIDPARAMS);
1894 ok(!locked_desc.lpSurface, "IDirectDrawSurface_Lock did not set lpSurface in the surface desc to zero.\n");
1897 hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1898 ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = NULL) failed (0x%08x)\n", hr);
1899 hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1900 ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned 0x%08x\n", hr);
1901 if(SUCCEEDED(hr)) {
1902 hr = IDirectDrawSurface_Unlock(surface, NULL);
1903 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1905 hr = IDirectDrawSurface_Unlock(surface, NULL);
1906 ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1908 memset(&locked_desc, 0, sizeof(locked_desc));
1909 locked_desc.dwSize = sizeof(locked_desc);
1910 hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1911 ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1912 valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1913 hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1914 ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1915 valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1917 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
1918 * Afterwards unlocking the surface fails(NULL rectangle, and both locked rectangles
1921 hr = IDirectDrawSurface_Unlock(surface, NULL);
1922 ok(hr == DD_OK, "Unlock returned (0x%08x)\n", hr);
1924 IDirectDrawSurface_Release(surface);
1928 static void CompressedTest(void)
1930 HRESULT hr;
1931 IDirectDrawSurface7 *surface;
1932 DDSURFACEDESC2 ddsd, ddsd2;
1933 IDirectDraw7 *dd7 = NULL;
1934 RECT r = { 0, 0, 128, 128 };
1935 RECT r2 = { 32, 32, 64, 64 };
1937 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1938 ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1940 memset(&ddsd, 0, sizeof(ddsd));
1941 ddsd.dwSize = sizeof(ddsd);
1942 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1943 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1944 ddsd.dwWidth = 128;
1945 ddsd.dwHeight = 128;
1946 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
1947 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
1948 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1950 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1951 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1952 if (FAILED(hr)) {
1953 skip("failed to create surface\n");
1954 return;
1957 memset(&ddsd2, 0, sizeof(ddsd2));
1958 ddsd2.dwSize = sizeof(ddsd2);
1959 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1960 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1961 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1963 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1964 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1965 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1966 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1967 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1968 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1969 ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1970 ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1971 IDirectDrawSurface7_Release(surface);
1973 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1974 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1975 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1976 if (FAILED(hr)) {
1977 skip("failed to create surface\n");
1978 return;
1981 memset(&ddsd2, 0, sizeof(ddsd2));
1982 ddsd2.dwSize = sizeof(ddsd2);
1983 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1984 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1985 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1987 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1988 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1989 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1990 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1991 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1992 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1993 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1994 IDirectDrawSurface7_Release(surface);
1996 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1997 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1998 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1999 if (FAILED(hr)) {
2000 skip("failed to create surface\n");
2001 return;
2004 memset(&ddsd2, 0, sizeof(ddsd2));
2005 ddsd2.dwSize = sizeof(ddsd2);
2006 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2007 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2008 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2010 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2011 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2012 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2013 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2014 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2015 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2016 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2017 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2019 memset(&ddsd2, 0, sizeof(ddsd2));
2020 ddsd2.dwSize = sizeof(ddsd2);
2021 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2023 /* Show that the description is not changed when locking the surface. What is really interesting
2024 * about this is that DDSD_LPSURFACE isn't set.
2026 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2027 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2029 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2030 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2031 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2032 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2033 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2034 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2035 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2036 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2038 hr = IDirectDrawSurface7_Unlock(surface, NULL);
2039 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2041 /* Now what about a locking rect? */
2042 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2043 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2045 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2046 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2047 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2048 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2049 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2050 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2051 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2052 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2054 hr = IDirectDrawSurface7_Unlock(surface, &r);
2055 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2057 /* Now what about a different locking offset? */
2058 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2059 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2061 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2062 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2063 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2064 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2065 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2066 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2067 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2068 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2070 hr = IDirectDrawSurface7_Unlock(surface, &r2);
2071 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2072 IDirectDrawSurface7_Release(surface);
2074 /* Try this with video memory. A kind of surprise. It still has the LINEARSIZE flag set,
2075 * but seems to have a pitch instead.
2077 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
2078 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2080 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2081 ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW || hr == DDERR_INVALIDPARAMS ||
2082 broken(hr == DDERR_NODIRECTDRAWHW), "CreateSurface returned %08x\n", hr);
2084 /* Not supported everywhere */
2085 if(SUCCEEDED(hr))
2087 memset(&ddsd2, 0, sizeof(ddsd2));
2088 ddsd2.dwSize = sizeof(ddsd2);
2089 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2090 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2091 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2093 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2094 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2095 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2096 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2097 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2098 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2099 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2100 ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2101 IDirectDrawSurface7_Release(surface);
2103 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2104 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2105 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2107 memset(&ddsd2, 0, sizeof(ddsd2));
2108 ddsd2.dwSize = sizeof(ddsd2);
2109 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2110 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2111 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2113 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2114 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2115 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2116 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2117 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2118 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2119 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2120 IDirectDrawSurface7_Release(surface);
2122 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2123 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2124 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2126 memset(&ddsd2, 0, sizeof(ddsd2));
2127 ddsd2.dwSize = sizeof(ddsd2);
2128 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2129 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2130 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2132 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2133 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2134 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2135 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2136 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2137 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2138 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2139 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2141 memset(&ddsd2, 0, sizeof(ddsd2));
2142 ddsd2.dwSize = sizeof(ddsd2);
2143 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2145 /* Show that the description is not changed when locking the surface. What is really interesting
2146 * about this is that DDSD_LPSURFACE isn't set.
2148 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2149 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2151 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2152 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2153 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2154 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2155 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2156 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2157 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2158 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2160 hr = IDirectDrawSurface7_Unlock(surface, NULL);
2161 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2163 /* Now what about a locking rect? */
2164 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2165 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2167 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2168 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2169 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2170 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2171 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2172 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2173 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2174 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2176 hr = IDirectDrawSurface7_Unlock(surface, &r);
2177 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2179 /* Now what about a different locking offset? */
2180 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2181 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2183 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2184 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2185 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2186 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2187 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2188 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2189 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2190 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2192 hr = IDirectDrawSurface7_Unlock(surface, &r2);
2193 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2195 IDirectDrawSurface7_Release(surface);
2197 else
2199 skip("Hardware DXTN textures not supported\n");
2202 /* What happens to managed textures? Interestingly, Windows reports them as being in system
2203 * memory. The linear size fits again.
2205 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2206 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
2207 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2209 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2210 ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW, "CreateSurface returned %08x\n", hr);
2212 /* Not supported everywhere */
2213 if(SUCCEEDED(hr))
2215 memset(&ddsd2, 0, sizeof(ddsd2));
2216 ddsd2.dwSize = sizeof(ddsd2);
2217 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2218 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2219 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2221 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2222 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2223 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2224 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2225 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2226 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2227 ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2228 ok(ddsd2.ddsCaps.dwCaps2 == DDSCAPS2_TEXTUREMANAGE, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2229 IDirectDrawSurface7_Release(surface);
2231 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2232 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2233 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2235 memset(&ddsd2, 0, sizeof(ddsd2));
2236 ddsd2.dwSize = sizeof(ddsd2);
2237 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2238 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2239 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2241 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2242 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2243 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2244 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2245 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2246 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2247 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2248 IDirectDrawSurface7_Release(surface);
2250 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2251 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2252 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2254 memset(&ddsd2, 0, sizeof(ddsd2));
2255 ddsd2.dwSize = sizeof(ddsd2);
2256 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2257 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2258 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2260 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2261 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2262 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2263 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2264 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2265 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2266 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2267 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2269 memset(&ddsd2, 0, sizeof(ddsd2));
2270 ddsd2.dwSize = sizeof(ddsd2);
2271 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2273 /* Show that the description is not changed when locking the surface. What is really interesting
2274 * about this is that DDSD_LPSURFACE isn't set.
2276 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2277 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2279 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2280 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2281 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2282 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2283 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2284 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2285 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2286 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2288 hr = IDirectDrawSurface7_Unlock(surface, NULL);
2289 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2291 /* Now what about a locking rect? */
2292 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2293 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2295 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2296 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2297 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2298 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2299 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2300 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2301 ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2302 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2304 hr = IDirectDrawSurface7_Unlock(surface, &r);
2305 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2307 /* Now what about a different locking offset? */
2308 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2309 ok(hr == DD_OK, "Lock returned %08x\n", hr);
2311 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2312 "Surface desc flags: %08x\n", ddsd2.dwFlags);
2313 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2314 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2315 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2316 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2317 ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2318 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2320 hr = IDirectDrawSurface7_Unlock(surface, &r2);
2321 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2323 IDirectDrawSurface7_Release(surface);
2325 else
2327 skip("Hardware DXTN textures not supported\n");
2330 IDirectDraw7_Release(dd7);
2333 static void SizeTest(void)
2335 LPDIRECTDRAWSURFACE dsurface = NULL;
2336 DDSURFACEDESC desc;
2337 HRESULT ret;
2338 HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2340 /* Create an offscreen surface surface without a size */
2341 ZeroMemory(&desc, sizeof(desc));
2342 desc.dwSize = sizeof(desc);
2343 desc.dwFlags = DDSD_CAPS;
2344 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2345 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2346 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without a size info returned %08x (dsurface=%p)\n", ret, dsurface);
2347 if(dsurface)
2349 trace("Surface at %p\n", dsurface);
2350 IDirectDrawSurface_Release(dsurface);
2351 dsurface = NULL;
2354 /* Create an offscreen surface surface with only a width parameter */
2355 ZeroMemory(&desc, sizeof(desc));
2356 desc.dwSize = sizeof(desc);
2357 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH;
2358 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2359 desc.dwWidth = 128;
2360 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2361 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without hight info returned %08x\n", ret);
2362 if(dsurface)
2364 IDirectDrawSurface_Release(dsurface);
2365 dsurface = NULL;
2368 /* Create an offscreen surface surface with only a height parameter */
2369 ZeroMemory(&desc, sizeof(desc));
2370 desc.dwSize = sizeof(desc);
2371 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT;
2372 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2373 desc.dwHeight = 128;
2374 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2375 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without width info returned %08x\n", ret);
2376 if(dsurface)
2378 IDirectDrawSurface_Release(dsurface);
2379 dsurface = NULL;
2382 /* Sanity check */
2383 ZeroMemory(&desc, sizeof(desc));
2384 desc.dwSize = sizeof(desc);
2385 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2386 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2387 desc.dwHeight = 128;
2388 desc.dwWidth = 128;
2389 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2390 ok(ret == DD_OK, "Creating an offscreen plain surface with width and height info returned %08x\n", ret);
2391 if(dsurface)
2393 IDirectDrawSurface_Release(dsurface);
2394 dsurface = NULL;
2397 /* Test a primary surface size */
2398 ret = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_NORMAL);
2399 ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2401 ZeroMemory(&desc, sizeof(desc));
2402 desc.dwSize = sizeof(desc);
2403 desc.dwFlags = DDSD_CAPS;
2404 desc.ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
2405 desc.dwHeight = 128; /* Keep them set to check what happens */
2406 desc.dwWidth = 128; /* Keep them set to check what happens */
2407 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2408 ok(ret == DD_OK, "Creating a primary surface without width and height info returned %08x\n", ret);
2409 if(dsurface)
2411 ret = IDirectDrawSurface_GetSurfaceDesc(dsurface, &desc);
2412 ok(ret == DD_OK, "GetSurfaceDesc returned %x\n", ret);
2414 IDirectDrawSurface_Release(dsurface);
2415 dsurface = NULL;
2417 ok(desc.dwFlags & DDSD_WIDTH, "Primary surface doesn't have width set\n");
2418 ok(desc.dwFlags & DDSD_HEIGHT, "Primary surface doesn't have height set\n");
2419 ok(desc.dwWidth == GetSystemMetrics(SM_CXSCREEN), "Surface width differs from screen width\n");
2420 ok(desc.dwHeight == GetSystemMetrics(SM_CYSCREEN), "Surface height differs from screen height\n");
2422 ret = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
2423 ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2426 static void PrivateDataTest(void)
2428 HRESULT hr;
2429 IDirectDrawSurface7 *surface7 = NULL;
2430 IDirectDrawSurface *surface = NULL;
2431 DDSURFACEDESC desc;
2432 ULONG ref, ref2;
2433 IUnknown *ptr;
2434 DWORD size = sizeof(IUnknown *);
2436 ZeroMemory(&desc, sizeof(desc));
2437 desc.dwSize = sizeof(desc);
2438 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2439 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2440 desc.dwHeight = 128;
2441 desc.dwWidth = 128;
2442 hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface, NULL);
2443 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2444 if(!surface)
2446 return;
2448 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **) &surface7);
2449 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2450 if(!surface7)
2452 IDirectDrawSurface_Release(surface);
2453 return;
2456 /* This fails */
2457 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 0, DDSPD_IUNKNOWNPOINTER);
2458 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2459 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 5, DDSPD_IUNKNOWNPOINTER);
2460 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2461 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *) * 2, DDSPD_IUNKNOWNPOINTER);
2462 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2464 ref = getref((IUnknown *) lpDD);
2465 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2466 ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2467 ref2 = getref((IUnknown *) lpDD);
2468 ok(ref2 == ref + 1, "Object reference is %d, expected %d\n", ref2, ref + 1);
2469 hr = IDirectDrawSurface7_FreePrivateData(surface7, &IID_IDirectDrawSurface7);
2470 ok(SUCCEEDED(hr), "IDirectDrawSurface7_FreePrivateData returned %#x.\n", hr);
2471 ref2 = getref((IUnknown *) lpDD);
2472 ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2474 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2475 ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2476 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, surface7, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2477 ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2478 ref2 = getref((IUnknown *) lpDD);
2479 ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2481 hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2482 ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2483 hr = IDirectDrawSurface7_GetPrivateData(surface7, &IID_IDirectDrawSurface7, &ptr, &size);
2484 ok(hr == DD_OK, "IDirectDrawSurface7_GetPrivateData failed with %08x\n", hr);
2485 ref2 = getref((IUnknown *) lpDD);
2486 /* Object is NOT being addrefed */
2487 ok(ptr == (IUnknown *) lpDD, "Returned interface pointer is %p, expected %p\n", ptr, lpDD);
2488 ok(ref2 == ref + 1, "Object reference is %d, expected %d. ptr at %p, orig at %p\n", ref2, ref + 1, ptr, lpDD);
2490 IDirectDrawSurface_Release(surface);
2491 IDirectDrawSurface7_Release(surface7);
2493 /* Destroying the surface frees the held reference */
2494 ref2 = getref((IUnknown *) lpDD);
2495 ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2498 static void BltParamTest(void)
2500 IDirectDrawSurface *surface1 = NULL, *surface2 = NULL;
2501 DDSURFACEDESC desc;
2502 HRESULT hr;
2503 DDBLTFX BltFx;
2504 RECT valid = {10, 10, 20, 20};
2505 RECT invalid1 = {20, 10, 10, 20};
2506 RECT invalid2 = {20, 20, 20, 20};
2507 RECT invalid3 = {-1, -1, 20, 20};
2508 RECT invalid4 = {60, 60, 70, 70};
2510 memset(&desc, 0, sizeof(desc));
2511 desc.dwSize = sizeof(desc);
2512 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2513 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2514 desc.dwHeight = 128;
2515 desc.dwWidth = 128;
2516 hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface1, NULL);
2517 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2519 desc.dwHeight = 64;
2520 desc.dwWidth = 64;
2521 hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface2, NULL);
2522 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2524 if(0)
2526 /* This crashes */
2527 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, NULL, NULL, 0);
2528 ok(hr == DD_OK, "BltFast from NULL surface returned %08x\n", hr);
2530 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, NULL, 0);
2531 ok(hr == DD_OK, "BltFast from smaller to bigger surface returned %08x\n", hr);
2532 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, NULL, 0);
2533 ok(hr == DDERR_INVALIDRECT, "BltFast from bigger to smaller surface returned %08x\n", hr);
2534 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &valid, 0);
2535 ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle returned %08x\n", hr);
2536 hr = IDirectDrawSurface_BltFast(surface2, 60, 60, surface1, &valid, 0);
2537 ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2538 hr = IDirectDrawSurface_BltFast(surface1, 90, 90, surface2, NULL, 0);
2539 ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2540 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid1, 0);
2541 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 1 returned %08x\n", hr);
2542 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid2, 0);
2543 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 2 returned %08x\n", hr);
2544 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid3, 0);
2545 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2546 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, &invalid4, 0);
2547 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2548 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface1, NULL, 0);
2549 ok(hr == DD_OK, "BltFast blitting a surface onto itself returned %08x\n", hr);
2551 /* Blt(non-fast) tests */
2552 memset(&BltFx, 0, sizeof(BltFx));
2553 BltFx.dwSize = sizeof(BltFx);
2554 U5(BltFx).dwFillColor = 0xaabbccdd;
2556 hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2557 ok(hr == DD_OK, "IDirectDrawSurface_Blt with a valid rectangle for color fill returned %08x\n", hr);
2558 hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, &invalid3, DDBLT_COLORFILL, &BltFx);
2559 ok(hr == DD_OK, "IDirectDrawSurface_Blt with a invalid, unused rectangle returned %08x\n", hr);
2560 hr = IDirectDrawSurface_Blt(surface2, &invalid1, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2561 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2562 hr = IDirectDrawSurface_Blt(surface2, &invalid2, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2563 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2564 hr = IDirectDrawSurface_Blt(surface2, &invalid3, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2565 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2566 hr = IDirectDrawSurface_Blt(surface2, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2567 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2569 /* Valid on surface 1 */
2570 hr = IDirectDrawSurface_Blt(surface1, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2571 ok(hr == DD_OK, "IDirectDrawSurface_Blt with a subrectangle fill returned %08x\n", hr);
2573 /* Works - stretched blit */
2574 hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, NULL, 0, NULL);
2575 ok(hr == DD_OK, "IDirectDrawSurface_Blt from a smaller to a bigger surface returned %08x\n", hr);
2576 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, NULL, 0, NULL);
2577 ok(hr == DD_OK, "IDirectDrawSurface_Blt from a bigger to a smaller surface %08x\n", hr);
2579 /* Invalid dest rects in sourced blits */
2580 hr = IDirectDrawSurface_Blt(surface2, &invalid1, surface1, NULL, 0, NULL);
2581 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2582 hr = IDirectDrawSurface_Blt(surface2, &invalid2, surface1, NULL, 0, NULL);
2583 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2584 hr = IDirectDrawSurface_Blt(surface2, &invalid3, surface1, NULL, 0, NULL);
2585 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2586 hr = IDirectDrawSurface_Blt(surface2, &invalid4, surface1, NULL, 0, NULL);
2587 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2589 /* Invalid src rects */
2590 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid1, 0, NULL);
2591 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2592 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid2, 0, NULL);
2593 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2594 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid3, 0, NULL);
2595 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2596 hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, &invalid4, 0, NULL);
2597 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2599 IDirectDrawSurface_Release(surface1);
2600 IDirectDrawSurface_Release(surface2);
2603 static void PaletteTest(void)
2605 HRESULT hr;
2606 LPDIRECTDRAWSURFACE lpSurf = NULL;
2607 DDSURFACEDESC ddsd;
2608 IDirectDrawPalette *palette = NULL;
2609 PALETTEENTRY Table[256];
2610 PALETTEENTRY palEntries[256];
2611 int i;
2613 for(i=0; i<256; i++)
2615 Table[i].peRed = 0xff;
2616 Table[i].peGreen = 0;
2617 Table[i].peBlue = 0;
2618 Table[i].peFlags = 0;
2621 /* Create a 8bit palette without DDPCAPS_ALLOW256 set */
2622 hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_8BIT, Table, &palette, NULL);
2623 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2624 if (FAILED(hr)) goto err;
2625 /* Read back the palette and verify the entries. Without DDPCAPS_ALLOW256 set
2626 / entry 0 and 255 should have been overwritten with black and white */
2627 IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2628 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2629 if(hr == DD_OK)
2631 ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2632 "Palette entry 0 of a palette without DDPCAPS_ALLOW256 set should be (0,0,0) but it is (%d,%d,%d)\n",
2633 palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2634 ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2635 "Palette entry 255 of a palette without DDPCAPS_ALLOW256 set should be (255,255,255) but it is (%d,%d,%d)\n",
2636 palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2638 /* Entry 1-254 should contain red */
2639 for(i=1; i<255; i++)
2640 ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2641 "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2642 i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2645 /* CreatePalette without DDPCAPS_ALLOW256 ignores entry 0 and 255,
2646 / now check we are able to update the entries afterwards. */
2647 IDirectDrawPalette_SetEntries(palette , 0, 0, 256, &Table[0]);
2648 ok(hr == DD_OK, "SetEntries failed with %08x\n", hr);
2649 IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2650 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2651 if(hr == DD_OK)
2653 ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2654 "Palette entry 0 should have been set to (0,0,0) but it contains (%d,%d,%d)\n",
2655 palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2656 ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2657 "Palette entry 255 should have been set to (255,255,255) but it contains (%d,%d,%d)\n",
2658 palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2660 IDirectDrawPalette_Release(palette);
2662 /* Create a 8bit palette with DDPCAPS_ALLOW256 set */
2663 hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
2664 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2665 if (FAILED(hr)) goto err;
2667 IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2668 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2669 if(hr == DD_OK)
2671 /* All entries should contain red */
2672 for(i=0; i<256; i++)
2673 ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2674 "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2675 i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2678 /* Try to set palette to a non-palettized surface */
2679 ddsd.dwSize = sizeof(ddsd);
2680 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2681 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2682 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2683 ddsd.dwWidth = 800;
2684 ddsd.dwHeight = 600;
2685 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2686 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
2687 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
2688 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
2689 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
2690 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurf, NULL);
2691 ok(hr==DD_OK, "CreateSurface returned: %x\n",hr);
2692 if (FAILED(hr)) {
2693 skip("failed to create surface\n");
2694 goto err;
2697 hr = IDirectDrawSurface_SetPalette(lpSurf, palette);
2698 ok(hr == DDERR_INVALIDPIXELFORMAT, "CreateSurface returned: %x\n",hr);
2700 IDirectDrawPalette_Release(palette);
2701 palette = NULL;
2703 hr = IDirectDrawSurface_GetPalette(lpSurf, &palette);
2704 ok(hr == DDERR_NOPALETTEATTACHED, "CreateSurface returned: %x\n",hr);
2706 err:
2708 if (lpSurf) IDirectDrawSurface_Release(lpSurf);
2709 if (palette) IDirectDrawPalette_Release(palette);
2712 static void StructSizeTest(void)
2714 IDirectDrawSurface *surface1;
2715 IDirectDrawSurface7 *surface7;
2716 union {
2717 DDSURFACEDESC desc1;
2718 DDSURFACEDESC2 desc2;
2719 char blob[1024]; /* To get a bunch of writable memory */
2720 } desc;
2721 DDSURFACEDESC create;
2722 HRESULT hr;
2724 memset(&desc, 0, sizeof(desc));
2725 memset(&create, 0, sizeof(create));
2727 memset(&create, 0, sizeof(create));
2728 create.dwSize = sizeof(create);
2729 create.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2730 create.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2731 create.dwHeight = 128;
2732 create.dwWidth = 128;
2733 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2734 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2735 hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface7, (void **) &surface7);
2736 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2738 desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2739 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2740 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2741 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2742 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2744 desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2745 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2746 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2747 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2748 ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2750 desc.desc2.dwSize = 0;
2751 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2752 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2753 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2754 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2756 desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2757 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2758 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2759 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2760 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2762 desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2763 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2764 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2765 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2766 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2768 /* Tests for Lock() */
2770 desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2771 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2772 ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2773 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2774 ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2775 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2776 ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2777 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2778 ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2780 desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2781 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2782 ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2783 ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2784 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2785 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2786 ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2787 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2788 ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2790 desc.desc2.dwSize = 0;
2791 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2792 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size 0 returned %08x\n", hr);
2793 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2794 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2795 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size 0 returned %08x\n", hr);
2796 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2798 desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2799 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2800 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2801 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2802 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2803 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2804 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2806 desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2807 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2808 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2809 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2810 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2811 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2812 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2814 IDirectDrawSurface7_Release(surface7);
2815 IDirectDrawSurface_Release(surface1);
2818 static void SurfaceCapsTest(void)
2820 DDSURFACEDESC create;
2821 DDSURFACEDESC desc;
2822 HRESULT hr;
2823 IDirectDrawSurface *surface1 = NULL;
2824 DDSURFACEDESC2 create2, desc2;
2825 IDirectDrawSurface7 *surface7 = NULL;
2826 IDirectDraw7 *dd7 = NULL;
2827 DWORD create_caps[] = {
2828 DDSCAPS_OFFSCREENPLAIN,
2829 DDSCAPS_TEXTURE,
2830 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD,
2832 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2833 DDSCAPS_PRIMARYSURFACE,
2834 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY
2836 DWORD expected_caps[] = {
2837 DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2838 DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2839 DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD,
2840 DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2841 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2842 DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_VISIBLE,
2843 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_VISIBLE
2845 UINT i;
2846 DDCAPS ddcaps;
2848 /* Tests various surface flags, what changes do they undergo during surface creation. Forsaken
2849 * engine expects texture surfaces without memory flag to get a video memory flag right after
2850 * creation. Currently, Wine adds DDSCAPS_FRONTBUFFER to primary surface, but native doesn't do this
2851 * for single buffered primaries. Because of this primary surface creation tests are todo_wine. No real
2852 * app is known so far to care about this. */
2853 ddcaps.dwSize = sizeof(DDCAPS);
2854 hr = IDirectDraw_GetCaps(lpDD, &ddcaps, NULL);
2855 ok(hr == DD_OK, "IDirectDraw_GetCaps failed with %08x\n", hr);
2857 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
2859 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
2860 return ;
2863 for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2865 memset(&create, 0, sizeof(create));
2866 create.dwSize = sizeof(create);
2867 create.ddsCaps.dwCaps = create_caps[i];
2868 create.dwFlags = DDSD_CAPS;
2870 if (!(create.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2872 create.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2873 create.dwHeight = 128;
2874 create.dwWidth = 128;
2877 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2878 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2880 if (SUCCEEDED(hr))
2882 memset(&desc, 0, sizeof(desc));
2883 desc.dwSize = sizeof(DDSURFACEDESC);
2884 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc);
2885 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2887 if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
2888 ok(desc.ddsCaps.dwCaps == expected_caps[i],
2889 "GetSurfaceDesc returned caps %x, expected %x\n", desc.ddsCaps.dwCaps,
2890 expected_caps[i]);
2891 else
2892 todo_wine ok(desc.ddsCaps.dwCaps == expected_caps[i],
2893 "GetSurfaceDesc returned caps %x, expected %x\n", desc.ddsCaps.dwCaps,
2894 expected_caps[i]);
2896 IDirectDrawSurface_Release(surface1);
2900 /* Test for differences in ddraw 7 */
2901 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2902 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
2903 if (FAILED(hr))
2905 skip("Failed to get IDirectDraw7 interface, skipping tests\n");
2907 else
2909 for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2911 memset(&create2, 0, sizeof(create2));
2912 create2.dwSize = sizeof(create2);
2913 create2.ddsCaps.dwCaps = create_caps[i];
2914 create2.dwFlags = DDSD_CAPS;
2916 if (!(create2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2918 create2.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2919 create2.dwHeight = 128;
2920 create2.dwWidth = 128;
2923 hr = IDirectDraw7_CreateSurface(dd7, &create2, &surface7, NULL);
2924 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2926 if (SUCCEEDED(hr))
2928 memset(&desc2, 0, sizeof(desc2));
2929 desc2.dwSize = sizeof(DDSURFACEDESC2);
2930 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc2);
2931 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2933 if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
2934 ok(desc2.ddsCaps.dwCaps == expected_caps[i],
2935 "GetSurfaceDesc returned caps %x, expected %x\n", desc2.ddsCaps.dwCaps,
2936 expected_caps[i]);
2937 else
2938 todo_wine ok(desc2.ddsCaps.dwCaps == expected_caps[i],
2939 "GetSurfaceDesc returned caps %x, expected %x\n", desc2.ddsCaps.dwCaps,
2940 expected_caps[i]);
2942 IDirectDrawSurface7_Release(surface7);
2946 IDirectDraw7_Release(dd7);
2949 memset(&create, 0, sizeof(create));
2950 create.dwSize = sizeof(create);
2951 create.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2952 create.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY;
2953 create.dwWidth = 64;
2954 create.dwHeight = 64;
2955 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2956 ok(hr == DDERR_INVALIDCAPS, "Creating a SYSMEM | VIDMEM surface returned 0x%08x, expected DDERR_INVALIDCAPS\n", hr);
2957 if(surface1) IDirectDrawSurface_Release(surface1);
2960 static BOOL can_create_primary_surface(void)
2962 DDSURFACEDESC ddsd;
2963 IDirectDrawSurface *surface;
2964 HRESULT hr;
2966 memset(&ddsd, 0, sizeof(ddsd));
2967 ddsd.dwSize = sizeof(ddsd);
2968 ddsd.dwFlags = DDSD_CAPS;
2969 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2970 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2971 if(FAILED(hr)) return FALSE;
2972 IDirectDrawSurface_Release(surface);
2973 return TRUE;
2976 static void dctest_surf(IDirectDrawSurface *surf, int ddsdver) {
2977 HRESULT hr;
2978 HDC dc, dc2 = (HDC) 0x1234;
2979 DDSURFACEDESC ddsd;
2980 DDSURFACEDESC2 ddsd2;
2982 memset(&ddsd, 0, sizeof(ddsd));
2983 ddsd.dwSize = sizeof(ddsd);
2984 memset(&ddsd2, 0, sizeof(ddsd2));
2985 ddsd2.dwSize = sizeof(ddsd2);
2987 hr = IDirectDrawSurface_GetDC(surf, &dc);
2988 ok(hr == DD_OK, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
2990 hr = IDirectDrawSurface_GetDC(surf, &dc2);
2991 ok(hr == DDERR_DCALREADYCREATED, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
2992 ok(dc2 == (HDC) 0x1234, "The failed GetDC call changed the dc: %p\n", dc2);
2994 hr = IDirectDrawSurface_Lock(surf, NULL, ddsdver == 1 ? &ddsd : ((DDSURFACEDESC *) &ddsd2), 0, NULL);
2995 ok(hr == DDERR_SURFACEBUSY, "IDirectDrawSurface_Lock returned 0x%08x, expected DDERR_ALREADYLOCKED\n", hr);
2997 hr = IDirectDrawSurface_ReleaseDC(surf, dc);
2998 ok(hr == DD_OK, "IDirectDrawSurface_ReleaseDC failed: 0x%08x\n", hr);
2999 hr = IDirectDrawSurface_ReleaseDC(surf, dc);
3000 ok(hr == DDERR_NODC, "IDirectDrawSurface_ReleaseDC returned 0x%08x, expected DDERR_NODC\n", hr);
3003 static void GetDCTest(void)
3005 DDSURFACEDESC ddsd;
3006 DDSURFACEDESC2 ddsd2;
3007 IDirectDrawSurface *surf;
3008 IDirectDrawSurface2 *surf2;
3009 IDirectDrawSurface4 *surf4;
3010 IDirectDrawSurface7 *surf7;
3011 IDirectDrawSurface *tmp;
3012 IDirectDrawSurface7 *tmp7;
3013 HRESULT hr;
3014 IDirectDraw2 *dd2;
3015 IDirectDraw4 *dd4;
3016 IDirectDraw7 *dd7;
3017 HDC dc;
3019 memset(&ddsd, 0, sizeof(ddsd));
3020 ddsd.dwSize = sizeof(ddsd);
3021 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3022 ddsd.dwWidth = 64;
3023 ddsd.dwHeight = 64;
3024 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3025 memset(&ddsd2, 0, sizeof(ddsd2));
3026 ddsd2.dwSize = sizeof(ddsd2);
3027 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3028 ddsd2.dwWidth = 64;
3029 ddsd2.dwHeight = 64;
3030 ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3032 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
3033 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3034 dctest_surf(surf, 1);
3035 IDirectDrawSurface_Release(surf);
3037 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3038 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3040 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3041 ok(hr == DD_OK, "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
3042 dctest_surf(surf, 1);
3044 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
3045 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr);
3046 dctest_surf((IDirectDrawSurface *) surf2, 1);
3048 IDirectDrawSurface2_Release(surf2);
3049 IDirectDrawSurface_Release(surf);
3050 IDirectDraw2_Release(dd2);
3052 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3053 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3055 surf = NULL;
3056 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3057 ok(hr == DD_OK, "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
3058 dctest_surf((IDirectDrawSurface *) surf4, 2);
3060 hr = IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)&surf);
3061 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3063 hr = IDirectDrawSurface4_GetDC(surf4, &dc);
3064 ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
3066 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, NULL);
3067 ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
3069 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
3070 ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
3071 ok(tmp == surf, "Expected surface %p, got %p.\n\n", surf, tmp);
3073 hr = IDirectDrawSurface4_ReleaseDC(surf4, dc);
3074 ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
3076 dc = CreateCompatibleDC(NULL);
3077 ok(!!dc, "CreateCompatibleDC failed.\n");
3079 tmp = (IDirectDrawSurface *)0xdeadbeef;
3080 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
3081 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3082 ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
3084 ok(DeleteDC(dc), "DeleteDC failed.\n");
3086 tmp = (IDirectDrawSurface *)0xdeadbeef;
3087 hr = IDirectDraw4_GetSurfaceFromDC(dd4, NULL, (IDirectDrawSurface4 **)&tmp);
3088 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3089 ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
3091 IDirectDrawSurface4_Release(surf4);
3092 IDirectDraw4_Release(dd4);
3094 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3095 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3096 surf = NULL;
3097 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3098 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
3099 dctest_surf((IDirectDrawSurface *) surf7, 2);
3101 hr = IDirectDrawSurface7_GetDC(surf7, &dc);
3102 ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
3104 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, NULL);
3105 ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
3107 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
3108 ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
3109 ok(tmp7 == surf7, "Expected surface %p, got %p.\n\n", surf7, tmp7);
3110 IDirectDrawSurface7_Release(tmp7);
3112 hr = IDirectDrawSurface7_ReleaseDC(surf7, dc);
3113 ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
3115 dc = CreateCompatibleDC(NULL);
3116 ok(!!dc, "CreateCompatibleDC failed.\n");
3118 tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
3119 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
3120 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3121 ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
3123 ok(DeleteDC(dc), "DeleteDC failed.\n");
3125 tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
3126 hr = IDirectDraw7_GetSurfaceFromDC(dd7, NULL, (IDirectDrawSurface7 **)&tmp7);
3127 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3128 ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
3130 IDirectDrawSurface7_Release(surf7);
3131 IDirectDraw7_Release(dd7);
3134 static void GetDCFormatTest(void)
3136 DDSURFACEDESC2 ddsd;
3137 unsigned int i;
3138 IDirectDrawSurface7 *surface;
3139 IDirectDraw7 *dd7;
3140 HRESULT hr;
3141 HDC dc;
3143 struct
3145 const char *name;
3146 DDPIXELFORMAT fmt;
3147 BOOL getdc_capable;
3148 HRESULT alt_result;
3149 } testdata[] = {
3151 "D3DFMT_A8R8G8B8",
3153 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3154 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
3156 TRUE
3159 "D3DFMT_X8R8G8B8",
3161 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3162 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
3164 TRUE
3167 "D3DFMT_X8B8G8R8",
3169 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3170 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
3172 TRUE,
3173 DDERR_CANTCREATEDC /* Vista+ */
3176 "D3DFMT_X8B8G8R8",
3178 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3179 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}
3181 TRUE,
3182 DDERR_CANTCREATEDC /* Vista+ */
3185 "D3DFMT_A4R4G4B4",
3187 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3188 {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}
3190 TRUE,
3191 DDERR_CANTCREATEDC /* Vista+ */
3194 "D3DFMT_X4R4G4B4",
3196 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3197 {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}
3199 TRUE,
3200 DDERR_CANTCREATEDC /* Vista+ */
3203 "D3DFMT_R5G6B5",
3205 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3206 {16}, {0x0000F800}, {0x000007E0}, {0x0000001F}, {0x00000000}
3208 TRUE
3211 "D3DFMT_A1R5G5B5",
3213 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3214 {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00008000}
3216 TRUE
3219 "D3DFMT_X1R5G5B5",
3221 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3222 {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00000000}
3224 TRUE
3227 "D3DFMT_R3G3B2",
3229 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3230 { 8}, {0x000000E0}, {0x0000001C}, {0x00000003}, {0x00000000}
3232 FALSE
3235 /* Untested, windows test machine didn't support this format */
3236 "D3DFMT_A2R10G10B10",
3238 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3239 {32}, {0xC0000000}, {0x3FF00000}, {0x000FFC00}, {0x000003FF}
3241 TRUE
3244 * GetDC on a P8 surface fails unless the display mode is 8 bpp. This is not
3245 * implemented in wine yet, so disable the test for now. Succeeding P8 getDC
3246 * calls are tested in the ddraw.visual test.
3249 "D3DFMT_P8",
3251 sizeof(DDPIXELFORMAT), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0,
3252 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3254 FALSE
3258 "D3DFMT_L8",
3260 sizeof(DDPIXELFORMAT), DDPF_LUMINANCE, 0,
3261 {8 }, {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}
3263 FALSE
3266 "D3DFMT_A8L8",
3268 sizeof(DDPIXELFORMAT), DDPF_ALPHAPIXELS | DDPF_LUMINANCE, 0,
3269 {16}, {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}
3271 FALSE
3274 "D3DFMT_DXT1",
3276 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','1'),
3277 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3279 FALSE
3282 "D3DFMT_DXT2",
3284 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','2'),
3285 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3287 FALSE
3290 "D3DFMT_DXT3",
3292 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','3'),
3293 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3295 FALSE
3298 "D3DFMT_DXT4",
3300 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','4'),
3301 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3303 FALSE
3306 "D3DFMT_DXT5",
3308 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','5'),
3309 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3311 FALSE
3315 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3316 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed, hr = 0x%08x\n", hr);
3318 for(i = 0; i < (sizeof(testdata) / sizeof(testdata[0])); i++)
3320 memset(&ddsd, 0, sizeof(ddsd));
3321 ddsd.dwSize = sizeof(ddsd);
3322 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3323 ddsd.dwWidth = 64;
3324 ddsd.dwHeight = 64;
3325 U4(ddsd).ddpfPixelFormat = testdata[i].fmt;
3326 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3328 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3329 if(FAILED(hr))
3331 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
3332 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
3333 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3334 if(FAILED(hr))
3336 skip("IDirectDraw7_CreateSurface failed, hr = 0x%08x, format %s\n", hr, testdata[i].name);
3337 continue;
3341 dc = (void *) 0x1234;
3342 hr = IDirectDrawSurface7_GetDC(surface, &dc);
3343 if(testdata[i].getdc_capable)
3345 ok(SUCCEEDED(hr) ||
3346 (testdata[i].alt_result && hr == testdata[i].alt_result),
3347 "GetDC on a %s surface failed(0x%08x), expected it to work\n",
3348 testdata[i].name, hr);
3350 else
3352 ok(FAILED(hr), "GetDC on a %s surface succeeded(0x%08x), expected it to fail\n",
3353 testdata[i].name, hr);
3356 if(SUCCEEDED(hr))
3358 IDirectDrawSurface7_ReleaseDC(surface, dc);
3359 ok(hr == DD_OK, "IDirectDrawSurface7_ReleaseDC failed, hr = 0x%08x\n", hr);
3360 dc = 0;
3362 else
3364 ok(dc == NULL, "After failed GetDC dc is %p\n", dc);
3367 IDirectDrawSurface7_Release(surface);
3370 IDirectDraw7_Release(dd7);
3373 START_TEST(dsurface)
3375 HRESULT ret;
3376 IDirectDraw4 *dd4;
3378 if (!CreateDirectDraw())
3379 return;
3381 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3382 if (ret == E_NOINTERFACE)
3384 win_skip("DirectDraw4 and higher are not supported\n");
3385 ReleaseDirectDraw();
3386 return;
3388 IDirectDraw_Release(dd4);
3390 if(!can_create_primary_surface())
3392 skip("Unable to create primary surface\n");
3393 return;
3396 MipMapCreationTest();
3397 SrcColorKey32BlitTest();
3398 QueryInterface();
3399 GetDDInterface_1();
3400 GetDDInterface_2();
3401 GetDDInterface_4();
3402 GetDDInterface_7();
3403 IFaceRefCount();
3404 EnumTest();
3405 AttachmentTest();
3406 AttachmentTest7();
3407 CubeMapTest();
3408 test_lockrect_invalid();
3409 CompressedTest();
3410 SizeTest();
3411 PrivateDataTest();
3412 BltParamTest();
3413 StructSizeTest();
3414 PaletteTest();
3415 SurfaceCapsTest();
3416 GetDCTest();
3417 GetDCFormatTest();
3418 ReleaseDirectDraw();