ddraw/tests: Fix double assigment to the same lvalue (coccinellery).
[wine.git] / dlls / ddraw / tests / dsurface.c
blob6ecf7fe606c1d54b31ac76a19b831eac8683e089
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-2009, 2011 Stefan Dösinger for CodeWeavers
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 "wine/test.h"
27 #include "wine/exception.h"
28 #include "ddraw.h"
29 #include "d3d.h"
30 #include "unknwn.h"
32 static HRESULT (WINAPI *pDirectDrawCreateEx)(GUID *, void **, REFIID, IUnknown *);
34 static IDirectDraw *lpDD;
35 static DDCAPS ddcaps;
37 static BOOL CreateDirectDraw(void)
39 HRESULT rc;
41 rc = DirectDrawCreate(NULL, &lpDD, NULL);
42 ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
43 if (!lpDD) {
44 trace("DirectDrawCreateEx() failed with an error %x\n", rc);
45 return FALSE;
48 rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
49 ok(rc==DD_OK,"SetCooperativeLevel returned: %x\n",rc);
51 return TRUE;
55 static void ReleaseDirectDraw(void)
57 if( lpDD != NULL )
59 IDirectDraw_Release(lpDD);
60 lpDD = NULL;
64 static void SrcColorKey32BlitTest(void)
66 IDirectDrawSurface *lpSrc;
67 IDirectDrawSurface *lpDst;
68 DDSURFACEDESC ddsd, ddsd2;
69 DDCOLORKEY DDColorKey;
70 LPDWORD lpData;
71 HRESULT rc;
72 DDBLTFX fx;
74 ddsd2.dwSize = sizeof(ddsd2);
75 ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
77 ddsd.dwSize = sizeof(ddsd);
78 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
79 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
80 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
81 ddsd.dwWidth = 800;
82 ddsd.dwHeight = 600;
83 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
84 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
85 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
86 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
87 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
88 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
89 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
90 if (FAILED(rc))
92 skip("failed to create surface\n");
93 return;
96 ddsd.dwFlags |= DDSD_CKSRCBLT;
97 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
98 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
99 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
100 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
101 if (FAILED(rc))
103 skip("failed to create surface\n");
104 return;
107 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
108 ok(rc==DD_OK,"Lock returned: %x\n",rc);
109 lpData = ddsd2.lpSurface;
110 lpData[0] = 0xCCCCCCCC;
111 lpData[1] = 0xCCCCCCCC;
112 lpData[2] = 0xCCCCCCCC;
113 lpData[3] = 0xCCCCCCCC;
115 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
116 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
118 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
119 ok(rc==DD_OK,"Lock returned: %x\n",rc);
120 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
121 lpData = ddsd2.lpSurface;
122 lpData[0] = 0x77010203;
123 lpData[1] = 0x00010203;
124 lpData[2] = 0x77FF00FF;
125 lpData[3] = 0x00FF00FF;
126 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
127 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
129 IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
131 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
132 ok(rc==DD_OK,"Lock returned: %x\n",rc);
133 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
134 lpData = ddsd2.lpSurface;
135 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
136 * color keying, but copy it to the destination surface. Others apply it for color keying, but
137 * do not copy it into the destination surface.
139 if(lpData[0]==0x00010203) {
140 trace("X channel was not copied into the destination surface\n");
141 ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
142 "Destination data after blitting is not correct\n");
143 } else {
144 ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
145 "Destination data after blitting is not correct\n");
147 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
148 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
150 /* Below we repeat the same test as above but now using BltFast instead of Blt. Before
151 * we can carry out the test we need to restore the color of the destination surface.
153 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
154 ok(rc==DD_OK,"Lock returned: %x\n",rc);
155 lpData = ddsd2.lpSurface;
156 lpData[0] = 0xCCCCCCCC;
157 lpData[1] = 0xCCCCCCCC;
158 lpData[2] = 0xCCCCCCCC;
159 lpData[3] = 0xCCCCCCCC;
160 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
161 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
163 IDirectDrawSurface_BltFast(lpDst, 0, 0, lpSrc, NULL, DDBLTFAST_SRCCOLORKEY);
165 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
166 ok(rc==DD_OK,"Lock returned: %x\n",rc);
167 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
168 lpData = ddsd2.lpSurface;
169 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
170 * color keying, but copy it to the destination surface. Others apply it for color keying, but
171 * do not copy it into the destination surface.
173 if(lpData[0]==0x00010203) {
174 trace("X channel was not copied into the destination surface\n");
175 ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
176 "Destination data after blitting is not correct\n");
177 } else {
178 ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
179 "Destination data after blitting is not correct\n");
181 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
182 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
184 /* Also test SetColorKey */
185 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
186 ok(DDColorKey.dwColorSpaceLowValue == 0xFF00FF && DDColorKey.dwColorSpaceHighValue == 0xFF00FF,
187 "GetColorKey does not return the colorkey used at surface creation\n");
189 DDColorKey.dwColorSpaceLowValue = 0x00FF00;
190 DDColorKey.dwColorSpaceHighValue = 0x00FF00;
191 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
193 DDColorKey.dwColorSpaceLowValue = 0;
194 DDColorKey.dwColorSpaceHighValue = 0;
195 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
196 ok(DDColorKey.dwColorSpaceLowValue == 0x00FF00 && DDColorKey.dwColorSpaceHighValue == 0x00FF00,
197 "GetColorKey does not return the colorkey set with SetColorKey\n");
199 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
200 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
201 IDirectDrawSurface_GetSurfaceDesc(lpSrc, &ddsd);
202 ok(ddsd.ddckCKSrcBlt.dwColorSpaceLowValue == 0x00FF00 && ddsd.ddckCKSrcBlt.dwColorSpaceHighValue == 0x00FF00,
203 "GetSurfaceDesc does not return the colorkey set with SetColorKey\n");
205 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
206 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
207 DDColorKey.dwColorSpaceHighValue = 0x000000;
208 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
210 DDColorKey.dwColorSpaceLowValue = 0;
211 DDColorKey.dwColorSpaceHighValue = 0;
212 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
213 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
214 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
216 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
217 DDColorKey.dwColorSpaceHighValue = 0x000001;
218 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
220 DDColorKey.dwColorSpaceLowValue = 0;
221 DDColorKey.dwColorSpaceHighValue = 0;
222 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
223 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
224 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
226 DDColorKey.dwColorSpaceLowValue = 0x0000FF;
227 DDColorKey.dwColorSpaceHighValue = 0x0000FE;
228 IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
230 DDColorKey.dwColorSpaceLowValue = 0;
231 DDColorKey.dwColorSpaceHighValue = 0;
232 IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
233 ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
234 "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
236 IDirectDrawSurface_Release(lpSrc);
237 IDirectDrawSurface_Release(lpDst);
239 /* start with a new set of surfaces to test the color keying parameters to blit */
240 memset(&ddsd, 0, sizeof(ddsd));
241 ddsd.dwSize = sizeof(ddsd);
242 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
243 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
244 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
245 ddsd.dwWidth = 800;
246 ddsd.dwHeight = 600;
247 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
248 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
249 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
250 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
251 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
252 ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0xFF0000;
253 ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0xFF0000;
254 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x00FF00;
255 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x00FF00;
256 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
257 ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
258 if(FAILED(rc))
260 skip("Failed to create surface\n");
261 return;
264 /* start with a new set of surfaces to test the color keying parameters to blit */
265 memset(&ddsd, 0, sizeof(ddsd));
266 ddsd.dwSize = sizeof(ddsd);
267 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
268 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
269 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
270 ddsd.dwWidth = 800;
271 ddsd.dwHeight = 600;
272 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
273 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
274 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
275 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
276 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
277 ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x0000FF;
278 ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x0000FF;
279 ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0x000000;
280 ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0x000000;
281 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
282 ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
283 if(FAILED(rc))
285 skip("Failed to create surface\n");
286 IDirectDrawSurface_Release(lpDst);
287 return;
290 memset(&fx, 0, sizeof(fx));
291 fx.dwSize = sizeof(fx);
292 fx.ddckSrcColorkey.dwColorSpaceHighValue = 0x110000;
293 fx.ddckSrcColorkey.dwColorSpaceLowValue = 0x110000;
294 fx.ddckDestColorkey.dwColorSpaceHighValue = 0x001100;
295 fx.ddckDestColorkey.dwColorSpaceLowValue = 0x001100;
297 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
298 ok(rc==DD_OK,"Lock returned: %x\n",rc);
299 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
300 lpData = ddsd2.lpSurface;
301 lpData[0] = 0x000000FF; /* Applies to src blt key in src surface */
302 lpData[1] = 0x00000000; /* Applies to dst blt key in src surface */
303 lpData[2] = 0x00FF0000; /* Dst color key in dst surface */
304 lpData[3] = 0x0000FF00; /* Src color key in dst surface */
305 lpData[4] = 0x00001100; /* Src color key in ddbltfx */
306 lpData[5] = 0x00110000; /* Dst color key in ddbltfx */
307 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
308 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
310 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
311 ok(rc==DD_OK,"Lock returned: %x\n",rc);
312 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
313 lpData = ddsd2.lpSurface;
314 lpData[0] = 0x55555555;
315 lpData[1] = 0x55555555;
316 lpData[2] = 0x55555555;
317 lpData[3] = 0x55555555;
318 lpData[4] = 0x55555555;
319 lpData[5] = 0x55555555;
320 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
321 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
323 /* Test a blit without keying */
324 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, 0, &fx);
325 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
327 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
328 ok(rc==DD_OK,"Lock returned: %x\n",rc);
329 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
330 lpData = ddsd2.lpSurface;
331 /* Should have copied src data unmodified to dst */
332 ok(lpData[0] == 0x000000FF &&
333 lpData[1] == 0x00000000 &&
334 lpData[2] == 0x00FF0000 &&
335 lpData[3] == 0x0000FF00 &&
336 lpData[4] == 0x00001100 &&
337 lpData[5] == 0x00110000, "Surface data after unkeyed blit does not match\n");
339 lpData[0] = 0x55555555;
340 lpData[1] = 0x55555555;
341 lpData[2] = 0x55555555;
342 lpData[3] = 0x55555555;
343 lpData[4] = 0x55555555;
344 lpData[5] = 0x55555555;
345 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
346 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
348 /* Src key */
349 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
350 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
352 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
353 ok(rc==DD_OK,"Lock returned: %x\n",rc);
354 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
355 lpData = ddsd2.lpSurface;
357 ok(lpData[0] == 0x55555555 && /* Here the src key applied */
358 lpData[1] == 0x00000000 &&
359 lpData[2] == 0x00FF0000 &&
360 lpData[3] == 0x0000FF00 &&
361 lpData[4] == 0x00001100 &&
362 lpData[5] == 0x00110000, "Surface data after srckey blit does not match\n");
364 lpData[0] = 0x55555555;
365 lpData[1] = 0x55555555;
366 lpData[2] = 0x55555555;
367 lpData[3] = 0x55555555;
368 lpData[4] = 0x55555555;
369 lpData[5] = 0x55555555;
370 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
371 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
373 /* Src override */
374 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
375 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
377 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
378 ok(rc==DD_OK,"Lock returned: %x\n",rc);
379 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
380 lpData = ddsd2.lpSurface;
382 ok(lpData[0] == 0x000000FF &&
383 lpData[1] == 0x00000000 &&
384 lpData[2] == 0x00FF0000 &&
385 lpData[3] == 0x0000FF00 &&
386 lpData[4] == 0x00001100 &&
387 lpData[5] == 0x55555555, /* Override key applies here */
388 "Surface data after src override key blit does not match\n");
390 lpData[0] = 0x55555555;
391 lpData[1] = 0x55555555;
392 lpData[2] = 0x55555555;
393 lpData[3] = 0x55555555;
394 lpData[4] = 0x55555555;
395 lpData[5] = 0x55555555;
396 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
397 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
399 /* Src override AND src key. That is not supposed to work */
400 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &fx);
401 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
403 /* Verify that the destination is unchanged */
404 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
405 ok(rc==DD_OK,"Lock returned: %x\n",rc);
406 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
407 lpData = ddsd2.lpSurface;
409 ok(lpData[0] == 0x55555555 &&
410 lpData[1] == 0x55555555 &&
411 lpData[2] == 0x55555555 &&
412 lpData[3] == 0x55555555 &&
413 lpData[4] == 0x55555555 &&
414 lpData[5] == 0x55555555, /* Override key applies here */
415 "Surface data after src key blit with override does not match\n");
417 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
418 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
419 lpData[2] = 0x00001100; /* Dest key in override */
420 lpData[3] = 0x00001100; /* Dest key in override */
421 lpData[4] = 0x00000000; /* Dest key in src surface */
422 lpData[5] = 0x00000000; /* Dest key in src surface */
423 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
424 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
426 /* Dest key blit */
427 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
428 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
430 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
431 ok(rc==DD_OK,"Lock returned: %x\n",rc);
432 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
433 lpData = ddsd2.lpSurface;
435 /* DirectDraw uses the dest blit key from the SOURCE surface ! */
436 ok(lpData[0] == 0x00ff0000 &&
437 lpData[1] == 0x00ff0000 &&
438 lpData[2] == 0x00001100 &&
439 lpData[3] == 0x00001100 &&
440 lpData[4] == 0x00001100 && /* Key applies here */
441 lpData[5] == 0x00110000, /* Key applies here */
442 "Surface data after dest key blit does not match\n");
444 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
445 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
446 lpData[2] = 0x00001100; /* Dest key in override */
447 lpData[3] = 0x00001100; /* Dest key in override */
448 lpData[4] = 0x00000000; /* Dest key in src surface */
449 lpData[5] = 0x00000000; /* Dest key in src surface */
450 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
451 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
453 /* Dest override key blit */
454 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
455 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
457 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
458 ok(rc==DD_OK,"Lock returned: %x\n",rc);
459 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
460 lpData = ddsd2.lpSurface;
462 ok(lpData[0] == 0x00FF0000 &&
463 lpData[1] == 0x00FF0000 &&
464 lpData[2] == 0x00FF0000 && /* Key applies here */
465 lpData[3] == 0x0000FF00 && /* Key applies here */
466 lpData[4] == 0x00000000 &&
467 lpData[5] == 0x00000000,
468 "Surface data after dest key override blit does not match\n");
470 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
471 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
472 lpData[2] = 0x00001100; /* Dest key in override */
473 lpData[3] = 0x00001100; /* Dest key in override */
474 lpData[4] = 0x00000000; /* Dest key in src surface */
475 lpData[5] = 0x00000000; /* Dest key in src surface */
476 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
477 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
479 /* Dest override key blit. Supposed to fail too */
480 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYDESTOVERRIDE, &fx);
481 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
483 /* Check for unchanged data */
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;
489 ok(lpData[0] == 0x00FF0000 &&
490 lpData[1] == 0x00FF0000 &&
491 lpData[2] == 0x00001100 && /* Key applies here */
492 lpData[3] == 0x00001100 && /* Key applies here */
493 lpData[4] == 0x00000000 &&
494 lpData[5] == 0x00000000,
495 "Surface data with dest key and dest override does not match\n");
497 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
498 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
499 lpData[2] = 0x00001100; /* Dest key in override */
500 lpData[3] = 0x00001100; /* Dest key in override */
501 lpData[4] = 0x00000000; /* Dest key in src surface */
502 lpData[5] = 0x00000000; /* Dest key in src surface */
503 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
504 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
506 /* Modify the source data a bit to give some more conclusive results */
507 rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
508 ok(rc==DD_OK,"Lock returned: %x\n",rc);
509 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
510 lpData = ddsd2.lpSurface;
511 lpData[5] = 0x000000FF; /* Applies to src blt key in src surface */
512 rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
513 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
515 /* Source and destination key */
516 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYSRC, &fx);
517 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
519 rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
520 ok(rc==DD_OK,"Lock returned: %x\n",rc);
521 ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
522 lpData = ddsd2.lpSurface;
524 ok(lpData[0] == 0x00FF0000 && /* Masked by Destination key */
525 lpData[1] == 0x00FF0000 && /* Masked by Destination key */
526 lpData[2] == 0x00001100 && /* Masked by Destination key */
527 lpData[3] == 0x00001100 && /* Masked by Destination key */
528 lpData[4] == 0x00001100 && /* Allowed by destination key, not masked by source key */
529 lpData[5] == 0x00000000, /* Allowed by dst key, but masked by source key */
530 "Surface data with src key and dest key blit does not match\n");
532 lpData[0] = 0x00FF0000; /* Dest key in dst surface */
533 lpData[1] = 0x00FF0000; /* Dest key in dst surface */
534 lpData[2] = 0x00001100; /* Dest key in override */
535 lpData[3] = 0x00001100; /* Dest key in override */
536 lpData[4] = 0x00000000; /* Dest key in src surface */
537 lpData[5] = 0x00000000; /* Dest key in src surface */
538 rc = IDirectDrawSurface_Unlock(lpDst, NULL);
539 ok(rc==DD_OK,"Unlock returned: %x\n",rc);
541 /* Override keys without ddbltfx parameter fail */
542 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, NULL);
543 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
544 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, NULL);
545 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
547 /* Try blitting without keys in the source surface*/
548 rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, NULL);
549 ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
550 rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_DESTBLT, NULL);
551 ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
553 /* That fails now. Do not bother to check that the data is unmodified */
554 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
555 ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
557 /* Dest key blit still works. Which key is used this time??? */
558 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
559 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
561 /* With correctly passed override keys no key in the surface is needed.
562 * Again, the result was checked before, no need to do that again
564 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
565 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
566 rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
567 ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
569 IDirectDrawSurface_Release(lpSrc);
570 IDirectDrawSurface_Release(lpDst);
573 static void QueryInterface(void)
575 IDirectDrawSurface *dsurface;
576 DDSURFACEDESC surface;
577 void *object;
578 HRESULT ret;
580 /* Create a surface */
581 ZeroMemory(&surface, sizeof(surface));
582 surface.dwSize = sizeof(surface);
583 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
584 surface.dwHeight = 10;
585 surface.dwWidth = 10;
586 ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
587 if(ret != DD_OK)
589 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
590 return;
593 /* Call IUnknown::QueryInterface */
594 ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
595 ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %x\n", ret);
597 IDirectDrawSurface_Release(dsurface);
600 /* The following tests test which interface is returned by IDirectDrawSurfaceX::GetDDInterface.
601 * It uses refcounts to test that and compares the interface addresses. Partially fits here, and
602 * partially in the refcount test
605 static ULONG getref(IUnknown *iface)
607 IUnknown_AddRef(iface);
608 return IUnknown_Release(iface);
611 static void GetDDInterface_1(void)
613 IDirectDrawSurface2 *dsurface2;
614 IDirectDrawSurface *dsurface;
615 DDSURFACEDESC surface;
616 HRESULT ret;
617 IDirectDraw2 *dd2;
618 IDirectDraw4 *dd4;
619 IDirectDraw7 *dd7;
620 ULONG ref1, ref2, ref4, ref7;
621 void *dd;
623 /* Create a surface */
624 ZeroMemory(&surface, sizeof(surface));
625 surface.dwSize = sizeof(surface);
626 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
627 surface.dwHeight = 10;
628 surface.dwWidth = 10;
629 ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
630 if(ret != DD_OK)
632 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
633 return;
635 ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
636 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
637 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
638 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
639 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
640 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
641 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
642 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
644 ref1 = getref((IUnknown *) lpDD);
645 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
646 ref2 = getref((IUnknown *) dd2);
647 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
648 ref4 = getref((IUnknown *) dd4);
649 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
650 ref7 = getref((IUnknown *) dd7);
651 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
654 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
655 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
656 ok(getref((IUnknown *) lpDD) == ref1 + 1, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
657 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
658 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
659 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
661 ok(dd == lpDD, "Returned interface pointer is not equal to the creation interface\n");
662 IUnknown_Release((IUnknown *) dd);
664 /* try a NULL pointer */
665 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, NULL);
666 ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
668 IDirectDraw_Release(dd2);
669 IDirectDraw_Release(dd4);
670 IDirectDraw_Release(dd7);
671 IDirectDrawSurface2_Release(dsurface2);
672 IDirectDrawSurface_Release(dsurface);
675 static void GetDDInterface_2(void)
677 IDirectDrawSurface2 *dsurface2;
678 IDirectDrawSurface *dsurface;
679 DDSURFACEDESC surface;
680 HRESULT ret;
681 IDirectDraw2 *dd2;
682 IDirectDraw4 *dd4;
683 IDirectDraw7 *dd7;
684 ULONG ref1, ref2, ref4, ref7;
685 void *dd;
687 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
688 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
689 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
690 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
691 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
692 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
694 /* Create a surface */
695 ZeroMemory(&surface, sizeof(surface));
696 surface.dwSize = sizeof(surface);
697 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
698 surface.dwHeight = 10;
699 surface.dwWidth = 10;
700 ret = IDirectDraw2_CreateSurface(dd2, &surface, &dsurface, NULL);
701 if(ret != DD_OK)
703 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
704 return;
706 ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
707 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
709 ref1 = getref((IUnknown *) lpDD);
710 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
711 ref2 = getref((IUnknown *) dd2);
712 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
713 ref4 = getref((IUnknown *) dd4);
714 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
715 ref7 = getref((IUnknown *) dd7);
716 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
719 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
720 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
721 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
722 ok(getref((IUnknown *) dd2) == ref2 + 1, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
723 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
724 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
726 ok(dd == dd2, "Returned interface pointer is not equal to the creation interface\n");
727 IUnknown_Release((IUnknown *) dd);
729 IDirectDraw_Release(dd2);
730 IDirectDraw_Release(dd4);
731 IDirectDraw_Release(dd7);
732 IDirectDrawSurface2_Release(dsurface2);
733 IDirectDrawSurface_Release(dsurface);
736 static void GetDDInterface_4(void)
738 IDirectDrawSurface4 *dsurface4;
739 IDirectDrawSurface2 *dsurface2;
740 DDSURFACEDESC2 surface;
741 HRESULT ret;
742 IDirectDraw2 *dd2;
743 IDirectDraw4 *dd4;
744 IDirectDraw7 *dd7;
745 ULONG ref1, ref2, ref4, ref7;
746 void *dd;
748 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
749 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
750 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
751 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
752 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
753 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
755 /* Create a surface */
756 ZeroMemory(&surface, sizeof(surface));
757 surface.dwSize = sizeof(surface);
758 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
759 surface.dwHeight = 10;
760 surface.dwWidth = 10;
761 ret = IDirectDraw4_CreateSurface(dd4, &surface, &dsurface4, NULL);
762 if(ret != DD_OK)
764 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
765 return;
767 ret = IDirectDrawSurface4_QueryInterface(dsurface4, &IID_IDirectDrawSurface2, (void **) &dsurface2);
768 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
770 ref1 = getref((IUnknown *) lpDD);
771 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
772 ref2 = getref((IUnknown *) dd2);
773 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
774 ref4 = getref((IUnknown *) dd4);
775 ok(ref4 == 2, "IDirectDraw4 refcount is %d\n", ref4);
776 ref7 = getref((IUnknown *) dd7);
777 ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
779 ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
780 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
781 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
782 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
783 ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
784 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
786 ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
787 IUnknown_Release((IUnknown *) dd);
789 /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
790 ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
791 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
792 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
793 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
794 ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
795 ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
797 ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
798 IUnknown_Release((IUnknown *) dd);
800 IDirectDraw_Release(dd2);
801 IDirectDraw_Release(dd4);
802 IDirectDraw_Release(dd7);
803 IDirectDrawSurface4_Release(dsurface4);
804 IDirectDrawSurface2_Release(dsurface2);
807 static void GetDDInterface_7(void)
809 IDirectDrawSurface7 *dsurface7;
810 IDirectDrawSurface4 *dsurface4;
811 DDSURFACEDESC2 surface;
812 HRESULT ret;
813 IDirectDraw2 *dd2;
814 IDirectDraw4 *dd4;
815 IDirectDraw7 *dd7;
816 ULONG ref1, ref2, ref4, ref7;
817 void *dd;
819 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
820 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
821 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
822 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
823 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
824 ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
826 /* Create a surface */
827 ZeroMemory(&surface, sizeof(surface));
828 surface.dwSize = sizeof(surface);
829 surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
830 surface.dwHeight = 10;
831 surface.dwWidth = 10;
832 ret = IDirectDraw7_CreateSurface(dd7, &surface, &dsurface7, NULL);
833 if(ret != DD_OK)
835 ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
836 return;
838 ret = IDirectDrawSurface7_QueryInterface(dsurface7, &IID_IDirectDrawSurface4, (void **) &dsurface4);
839 ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
841 ref1 = getref((IUnknown *) lpDD);
842 ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
843 ref2 = getref((IUnknown *) dd2);
844 ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
845 ref4 = getref((IUnknown *) dd4);
846 ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
847 ref7 = getref((IUnknown *) dd7);
848 ok(ref7 == 2, "IDirectDraw7 refcount is %d\n", ref7);
850 ret = IDirectDrawSurface7_GetDDInterface(dsurface7, &dd);
851 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
852 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
853 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
854 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
855 ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
857 ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
858 IUnknown_Release((IUnknown *) dd);
860 /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
861 ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
862 ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
863 ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
864 ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
865 ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
866 ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
868 ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
869 IUnknown_Release((IUnknown *) dd);
871 IDirectDraw_Release(dd2);
872 IDirectDraw_Release(dd4);
873 IDirectDraw_Release(dd7);
874 IDirectDrawSurface4_Release(dsurface4);
875 IDirectDrawSurface7_Release(dsurface7);
878 static ULONG getRefcount(IUnknown *iface)
880 IUnknown_AddRef(iface);
881 return IUnknown_Release(iface);
884 #define MAXEXPECTED 8 /* Can match up to 8 expected surfaces */
885 struct enumstruct
887 IDirectDrawSurface *expected[MAXEXPECTED];
888 UINT count;
891 static HRESULT WINAPI enumCB(IDirectDrawSurface *surf, DDSURFACEDESC *desc, void *ctx)
893 int i;
894 BOOL found = FALSE;
896 for(i = 0; i < MAXEXPECTED; i++)
898 if(((struct enumstruct *)ctx)->expected[i] == surf) found = TRUE;
901 ok(found, "Unexpected surface %p enumerated\n", surf);
902 ((struct enumstruct *)ctx)->count++;
903 IDirectDrawSurface_Release(surf);
904 return DDENUMRET_OK;
907 static void EnumTest(void)
909 HRESULT rc;
910 DDSURFACEDESC ddsd;
911 IDirectDrawSurface *surface;
912 struct enumstruct ctx;
914 ddsd.dwSize = sizeof(ddsd);
915 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
916 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
917 U2(ddsd).dwMipMapCount = 3;
918 ddsd.dwWidth = 32;
919 ddsd.dwHeight = 32;
920 rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
921 ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
923 memset(&ctx, 0, sizeof(ctx));
924 ctx.expected[0] = surface;
925 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[0], &ddsd.ddsCaps, &ctx.expected[1]);
926 ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
927 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[1], &ddsd.ddsCaps, &ctx.expected[2]);
928 ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
929 rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[2], &ddsd.ddsCaps, &ctx.expected[3]);
930 ok(rc == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", rc);
931 ok(!ctx.expected[3], "expected NULL pointer\n");
932 ctx.count = 0;
934 rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, &ddsd, &ctx, enumCB);
935 ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
936 ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
938 ctx.count = 0;
939 rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, NULL, &ctx, enumCB);
940 ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
941 ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
943 IDirectDrawSurface_Release(ctx.expected[2]);
944 IDirectDrawSurface_Release(ctx.expected[1]);
945 IDirectDrawSurface_Release(surface);
948 struct compare
950 DWORD width, height;
951 DWORD caps, caps2;
952 UINT mipmaps;
955 static HRESULT WINAPI CubeTestPaletteEnum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
957 HRESULT hr;
959 hr = IDirectDrawSurface7_SetPalette(surface, context);
960 if (desc->dwWidth == 64) /* This is for first mimpmap */
961 ok(hr == DDERR_NOTONMIPMAPSUBLEVEL, "SetPalette returned: %x\n",hr);
962 else
963 ok(hr == DD_OK, "SetPalette returned: %x\n",hr);
965 IDirectDrawSurface7_Release(surface);
967 return DDENUMRET_OK;
970 static HRESULT WINAPI CubeTestLvl2Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
972 UINT *mipmaps = context;
974 (*mipmaps)++;
975 IDirectDrawSurface7_EnumAttachedSurfaces(surface,
976 context,
977 CubeTestLvl2Enum);
979 return DDENUMRET_OK;
982 static HRESULT WINAPI CubeTestLvl1Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
984 UINT mipmaps = 0;
985 UINT *num = context;
986 static const struct compare expected[] =
989 128, 128,
990 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
991 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ,
995 128, 128,
996 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
997 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ,
1001 128, 128,
1002 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1003 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY,
1007 128, 128,
1008 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1009 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY,
1013 128, 128,
1014 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1015 DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX,
1019 64, 64, /* This is the first mipmap */
1020 DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1021 DDSCAPS2_MIPMAPSUBLEVEL | DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX,
1026 mipmaps = 0;
1027 IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1028 &mipmaps,
1029 CubeTestLvl2Enum);
1031 ok(desc->dwWidth == expected[*num].width, "Surface width is %d expected %d\n", desc->dwWidth, expected[*num].width);
1032 ok(desc->dwHeight == expected[*num].height, "Surface height is %d expected %d\n", desc->dwHeight, expected[*num].height);
1033 ok(desc->ddsCaps.dwCaps == expected[*num].caps, "Surface caps are %08x expected %08x\n", desc->ddsCaps.dwCaps, expected[*num].caps);
1034 ok(desc->ddsCaps.dwCaps2 == expected[*num].caps2, "Surface caps2 are %08x expected %08x\n", desc->ddsCaps.dwCaps2, expected[*num].caps2);
1035 ok(mipmaps == expected[*num].mipmaps, "Surface has %d mipmaps, expected %d\n", mipmaps, expected[*num].mipmaps);
1037 (*num)++;
1039 IDirectDrawSurface7_Release(surface);
1041 return DDENUMRET_OK;
1044 static void CubeMapTest(void)
1046 IDirectDraw7 *dd7 = NULL;
1047 IDirectDrawSurface7 *cubemap = NULL;
1048 IDirectDrawPalette *palette = NULL;
1049 DDSURFACEDESC2 ddsd;
1050 HRESULT hr;
1051 PALETTEENTRY Table[256];
1052 int i;
1053 UINT num = 0;
1054 UINT ref;
1055 struct enumstruct ctx;
1057 for(i=0; i<256; i++)
1059 Table[i].peRed = 0xff;
1060 Table[i].peGreen = 0;
1061 Table[i].peBlue = 0;
1062 Table[i].peFlags = 0;
1065 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1066 ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1067 if (FAILED(hr)) goto err;
1069 memset(&ddsd, 0, sizeof(ddsd));
1070 ddsd.dwSize = sizeof(ddsd);
1071 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1072 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1073 ddsd.dwWidth = 128;
1074 ddsd.dwHeight = 128;
1075 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1076 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1078 /* D3DFMT_R5G6B5 */
1079 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1080 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1081 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1082 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1083 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1085 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1086 if (FAILED(hr))
1088 skip("Can't create cubemap surface\n");
1089 goto err;
1092 hr = IDirectDrawSurface7_GetSurfaceDesc(cubemap, &ddsd);
1093 ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
1094 ok(ddsd.ddsCaps.dwCaps == (DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX),
1095 "Root Caps are %08x\n", ddsd.ddsCaps.dwCaps);
1096 ok(ddsd.ddsCaps.dwCaps2 == (DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP),
1097 "Root Caps2 are %08x\n", ddsd.ddsCaps.dwCaps2);
1099 IDirectDrawSurface7_EnumAttachedSurfaces(cubemap,
1100 &num,
1101 CubeTestLvl1Enum);
1102 ok(num == 6, "Surface has %d attachments\n", num);
1103 IDirectDrawSurface7_Release(cubemap);
1105 /* What happens if I do not specify any faces? */
1106 memset(&ddsd, 0, sizeof(ddsd));
1107 ddsd.dwSize = sizeof(ddsd);
1108 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1109 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1110 ddsd.dwWidth = 128;
1111 ddsd.dwHeight = 128;
1112 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1113 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP;
1115 /* D3DFMT_R5G6B5 */
1116 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1117 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1118 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1119 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1120 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1122 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1123 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7::CreateSurface asking for a cube map without faces returned %08x\n", hr);
1125 /* Cube map faces without a cube map? */
1126 memset(&ddsd, 0, sizeof(ddsd));
1127 ddsd.dwSize = sizeof(ddsd);
1128 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1129 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1130 ddsd.dwWidth = 128;
1131 ddsd.dwHeight = 128;
1132 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1133 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_ALLFACES;
1135 /* D3DFMT_R5G6B5 */
1136 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1137 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1138 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1139 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1140 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1142 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1143 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1145 memset(&ddsd, 0, sizeof(ddsd));
1146 ddsd.dwSize = sizeof(ddsd);
1147 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1148 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1149 ddsd.dwWidth = 128;
1150 ddsd.dwHeight = 128;
1151 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1152 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEX;
1154 /* D3DFMT_R5G6B5 */
1155 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1156 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1157 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1158 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1159 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1161 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1162 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1164 memset(&ddsd, 0, sizeof(ddsd));
1165 ddsd.dwSize = sizeof(ddsd);
1166 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1167 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1168 ddsd.dwWidth = 128;
1169 ddsd.dwHeight = 128;
1170 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1171 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1173 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1174 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;
1176 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1177 if (FAILED(hr))
1179 skip("Can't create palletized cubemap surface\n");
1180 goto err;
1183 hr = IDirectDraw7_CreatePalette(dd7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
1184 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
1186 hr = IDirectDrawSurface7_EnumAttachedSurfaces(cubemap, palette, CubeTestPaletteEnum);
1187 ok(hr == DD_OK, "EnumAttachedSurfaces failed\n");
1189 ref = getRefcount((IUnknown *) palette);
1190 ok(ref == 6, "Refcount is %u, expected 1\n", ref);
1192 IDirectDrawSurface7_Release(cubemap);
1194 ref = getRefcount((IUnknown *) palette);
1195 ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1197 IDirectDrawPalette_Release(palette);
1199 /* Make sure everything is cleaned up properly. Use the enumSurfaces test infrastructure */
1200 memset(&ctx, 0, sizeof(ctx));
1201 memset(&ddsd, 0, sizeof(ddsd));
1202 ddsd.dwSize = sizeof(DDSURFACEDESC);
1203 hr = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, (DDSURFACEDESC *) &ddsd, (void *) &ctx, enumCB);
1204 ok(hr == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", hr);
1205 ok(ctx.count == 0, "%d surfaces enumerated, expected 0\n", ctx.count);
1207 err:
1208 if (dd7) IDirectDraw7_Release(dd7);
1211 static void CompressedTest(void)
1213 HRESULT hr;
1214 IDirectDrawSurface7 *surface;
1215 DDSURFACEDESC2 ddsd, ddsd2;
1216 IDirectDraw7 *dd7 = NULL;
1217 RECT r = { 0, 0, 128, 128 };
1218 RECT r2 = { 32, 32, 64, 64 };
1220 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1221 ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1223 memset(&ddsd, 0, sizeof(ddsd));
1224 ddsd.dwSize = sizeof(ddsd);
1225 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1226 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1227 ddsd.dwWidth = 128;
1228 ddsd.dwHeight = 128;
1229 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
1230 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
1231 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1233 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1234 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1235 if (FAILED(hr))
1237 skip("failed to create surface\n");
1238 return;
1241 memset(&ddsd2, 0, sizeof(ddsd2));
1242 ddsd2.dwSize = sizeof(ddsd2);
1243 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1244 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1245 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1247 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1248 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1249 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1250 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1251 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1252 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1253 ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1254 ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1255 IDirectDrawSurface7_Release(surface);
1257 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1258 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1259 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1260 if (FAILED(hr))
1262 skip("failed to create surface\n");
1263 return;
1266 memset(&ddsd2, 0, sizeof(ddsd2));
1267 ddsd2.dwSize = sizeof(ddsd2);
1268 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1269 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1270 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1272 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1273 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1274 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1275 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1276 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1277 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1278 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1279 IDirectDrawSurface7_Release(surface);
1281 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1282 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1283 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1284 if (FAILED(hr))
1286 skip("failed to create surface\n");
1287 return;
1290 memset(&ddsd2, 0, sizeof(ddsd2));
1291 ddsd2.dwSize = sizeof(ddsd2);
1292 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1293 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1294 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1296 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1297 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1298 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1299 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1300 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1301 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1302 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1303 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
1305 memset(&ddsd2, 0, sizeof(ddsd2));
1306 ddsd2.dwSize = sizeof(ddsd2);
1307 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1309 /* Show that the description is not changed when locking the surface. What is really interesting
1310 * about this is that DDSD_LPSURFACE isn't set.
1312 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
1313 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1315 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1316 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1317 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1318 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1319 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1320 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1321 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1322 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1324 hr = IDirectDrawSurface7_Unlock(surface, NULL);
1325 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1327 /* Now what about a locking rect? */
1328 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
1329 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1331 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1332 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1333 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1334 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1335 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1336 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1337 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1338 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1340 hr = IDirectDrawSurface7_Unlock(surface, &r);
1341 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1343 /* Now what about a different locking offset? */
1344 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
1345 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1347 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1348 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1349 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1350 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1351 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1352 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1353 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1354 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1356 hr = IDirectDrawSurface7_Unlock(surface, &r2);
1357 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1358 IDirectDrawSurface7_Release(surface);
1360 /* Try this with video memory. A kind of surprise. It still has the LINEARSIZE flag set,
1361 * but seems to have a pitch instead.
1363 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
1364 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1366 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1367 ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW || hr == DDERR_INVALIDPARAMS ||
1368 broken(hr == DDERR_NODIRECTDRAWHW), "CreateSurface returned %08x\n", hr);
1370 /* Not supported everywhere */
1371 if(SUCCEEDED(hr))
1373 memset(&ddsd2, 0, sizeof(ddsd2));
1374 ddsd2.dwSize = sizeof(ddsd2);
1375 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1376 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1377 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1379 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1380 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1381 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1382 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1383 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1384 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1385 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1386 ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1387 IDirectDrawSurface7_Release(surface);
1389 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1390 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1391 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1393 memset(&ddsd2, 0, sizeof(ddsd2));
1394 ddsd2.dwSize = sizeof(ddsd2);
1395 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1396 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1397 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1399 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1400 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1401 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1402 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1403 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1404 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1405 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1406 IDirectDrawSurface7_Release(surface);
1408 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1409 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1410 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1412 memset(&ddsd2, 0, sizeof(ddsd2));
1413 ddsd2.dwSize = sizeof(ddsd2);
1414 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1415 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1416 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1418 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1419 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1420 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1421 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1422 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1423 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1424 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1425 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
1427 memset(&ddsd2, 0, sizeof(ddsd2));
1428 ddsd2.dwSize = sizeof(ddsd2);
1429 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1431 /* Show that the description is not changed when locking the surface. What is really interesting
1432 * about this is that DDSD_LPSURFACE isn't set.
1434 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
1435 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1437 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1438 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1439 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1440 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1441 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1442 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1443 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1444 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1446 hr = IDirectDrawSurface7_Unlock(surface, NULL);
1447 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1449 /* Now what about a locking rect? */
1450 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
1451 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1453 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1454 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1455 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1456 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1457 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1458 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1459 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1460 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1462 hr = IDirectDrawSurface7_Unlock(surface, &r);
1463 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1465 /* Now what about a different locking offset? */
1466 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
1467 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1469 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1470 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1471 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1472 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1473 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1474 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1475 /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1476 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1478 hr = IDirectDrawSurface7_Unlock(surface, &r2);
1479 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1481 IDirectDrawSurface7_Release(surface);
1483 else
1485 skip("Hardware DXTN textures not supported\n");
1488 /* What happens to managed textures? Interestingly, Windows reports them as being in system
1489 * memory. The linear size fits again.
1491 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1492 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
1493 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1495 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1496 ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW, "CreateSurface returned %08x\n", hr);
1498 /* Not supported everywhere */
1499 if(SUCCEEDED(hr))
1501 memset(&ddsd2, 0, sizeof(ddsd2));
1502 ddsd2.dwSize = sizeof(ddsd2);
1503 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1504 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1505 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1507 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1508 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1509 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1510 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1511 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1512 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1513 ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1514 ok(ddsd2.ddsCaps.dwCaps2 == DDSCAPS2_TEXTUREMANAGE, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1515 IDirectDrawSurface7_Release(surface);
1517 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1518 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1519 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1521 memset(&ddsd2, 0, sizeof(ddsd2));
1522 ddsd2.dwSize = sizeof(ddsd2);
1523 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1524 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1525 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1527 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1528 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1529 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1530 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1531 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1532 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1533 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1534 IDirectDrawSurface7_Release(surface);
1536 U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1537 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1538 ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1540 memset(&ddsd2, 0, sizeof(ddsd2));
1541 ddsd2.dwSize = sizeof(ddsd2);
1542 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1543 hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1544 ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1546 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1547 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1548 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1549 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1550 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1551 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1552 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1553 ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
1555 memset(&ddsd2, 0, sizeof(ddsd2));
1556 ddsd2.dwSize = sizeof(ddsd2);
1557 U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1559 /* Show that the description is not changed when locking the surface. What is really interesting
1560 * about this is that DDSD_LPSURFACE isn't set.
1562 hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
1563 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1565 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1566 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1567 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1568 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1569 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1570 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1571 ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1572 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1574 hr = IDirectDrawSurface7_Unlock(surface, NULL);
1575 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1577 /* Now what about a locking rect? */
1578 hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
1579 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1581 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1582 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1583 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1584 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1585 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1586 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1587 ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
1588 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1590 hr = IDirectDrawSurface7_Unlock(surface, &r);
1591 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1593 /* Now what about a different locking offset? */
1594 hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
1595 ok(hr == DD_OK, "Lock returned %08x\n", hr);
1597 ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1598 "Surface desc flags: %08x\n", ddsd2.dwFlags);
1599 ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1600 ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1601 ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1602 "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1603 ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
1604 ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1606 hr = IDirectDrawSurface7_Unlock(surface, &r2);
1607 ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1609 IDirectDrawSurface7_Release(surface);
1611 else
1613 skip("Hardware DXTN textures not supported\n");
1616 IDirectDraw7_Release(dd7);
1619 static void SizeTest(void)
1621 IDirectDrawSurface *dsurface = NULL;
1622 DDSURFACEDESC desc;
1623 HRESULT ret;
1624 HWND window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1625 100, 100, 160, 160, NULL, NULL, NULL, NULL);
1627 /* Create an offscreen surface surface without a size */
1628 ZeroMemory(&desc, sizeof(desc));
1629 desc.dwSize = sizeof(desc);
1630 desc.dwFlags = DDSD_CAPS;
1631 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
1632 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1633 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without a size info returned %08x (dsurface=%p)\n", ret, dsurface);
1634 if(dsurface)
1636 trace("Surface at %p\n", dsurface);
1637 IDirectDrawSurface_Release(dsurface);
1638 dsurface = NULL;
1641 /* Create an offscreen surface surface with only a width parameter */
1642 ZeroMemory(&desc, sizeof(desc));
1643 desc.dwSize = sizeof(desc);
1644 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH;
1645 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
1646 desc.dwWidth = 128;
1647 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1648 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without height info returned %08x\n", ret);
1649 if(dsurface)
1651 IDirectDrawSurface_Release(dsurface);
1652 dsurface = NULL;
1655 /* Create an offscreen surface surface with only a height parameter */
1656 ZeroMemory(&desc, sizeof(desc));
1657 desc.dwSize = sizeof(desc);
1658 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT;
1659 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
1660 desc.dwHeight = 128;
1661 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1662 ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without width info returned %08x\n", ret);
1663 if(dsurface)
1665 IDirectDrawSurface_Release(dsurface);
1666 dsurface = NULL;
1669 /* Test 0 height. */
1670 memset(&desc, 0, sizeof(desc));
1671 desc.dwSize = sizeof(desc);
1672 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1673 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1674 desc.dwWidth = 1;
1675 desc.dwHeight = 0;
1676 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1677 ok(ret == DDERR_INVALIDPARAMS, "Creating a 0 height surface returned %#x, expected DDERR_INVALIDPARAMS.\n", ret);
1678 if (SUCCEEDED(ret)) IDirectDrawSurface_Release(dsurface);
1679 dsurface = NULL;
1681 /* Test 0 width. */
1682 memset(&desc, 0, sizeof(desc));
1683 desc.dwSize = sizeof(desc);
1684 desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1685 desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1686 desc.dwWidth = 0;
1687 desc.dwHeight = 1;
1688 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1689 ok(ret == DDERR_INVALIDPARAMS, "Creating a 0 width surface returned %#x, expected DDERR_INVALIDPARAMS.\n", ret);
1690 if (SUCCEEDED(ret)) IDirectDrawSurface_Release(dsurface);
1691 dsurface = NULL;
1693 /* Sanity check */
1694 ZeroMemory(&desc, sizeof(desc));
1695 desc.dwSize = sizeof(desc);
1696 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
1697 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
1698 desc.dwHeight = 128;
1699 desc.dwWidth = 128;
1700 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1701 ok(ret == DD_OK, "Creating an offscreen plain surface with width and height info returned %08x\n", ret);
1702 if(dsurface)
1704 IDirectDrawSurface_Release(dsurface);
1705 dsurface = NULL;
1708 /* Test a primary surface size */
1709 ret = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_NORMAL);
1710 ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
1712 ZeroMemory(&desc, sizeof(desc));
1713 desc.dwSize = sizeof(desc);
1714 desc.dwFlags = DDSD_CAPS;
1715 desc.ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
1716 desc.dwHeight = 128; /* Keep them set to check what happens */
1717 desc.dwWidth = 128; /* Keep them set to check what happens */
1718 ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
1719 ok(ret == DD_OK, "Creating a primary surface without width and height info returned %08x\n", ret);
1720 if(dsurface)
1722 ret = IDirectDrawSurface_GetSurfaceDesc(dsurface, &desc);
1723 ok(ret == DD_OK, "GetSurfaceDesc returned %x\n", ret);
1725 IDirectDrawSurface_Release(dsurface);
1726 dsurface = NULL;
1728 ok(desc.dwFlags & DDSD_WIDTH, "Primary surface doesn't have width set\n");
1729 ok(desc.dwFlags & DDSD_HEIGHT, "Primary surface doesn't have height set\n");
1730 ok(desc.dwWidth == GetSystemMetrics(SM_CXSCREEN), "Surface width differs from screen width\n");
1731 ok(desc.dwHeight == GetSystemMetrics(SM_CYSCREEN), "Surface height differs from screen height\n");
1733 ret = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
1734 ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
1737 static void BltParamTest(void)
1739 IDirectDrawSurface *surface1 = NULL, *surface2 = NULL;
1740 DDSURFACEDESC desc;
1741 HRESULT hr;
1742 DDBLTFX BltFx;
1743 RECT valid = {10, 10, 20, 20};
1744 RECT invalid1 = {20, 10, 10, 20};
1745 RECT invalid2 = {20, 20, 20, 20};
1746 RECT invalid3 = {-1, -1, 20, 20};
1747 RECT invalid4 = {60, 60, 70, 70};
1749 memset(&desc, 0, sizeof(desc));
1750 desc.dwSize = sizeof(desc);
1751 desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
1752 desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
1753 desc.dwHeight = 128;
1754 desc.dwWidth = 128;
1755 hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface1, NULL);
1756 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
1758 desc.dwHeight = 64;
1759 desc.dwWidth = 64;
1760 hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface2, NULL);
1761 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
1763 if(0)
1765 /* This crashes */
1766 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, NULL, NULL, 0);
1767 ok(hr == DD_OK, "BltFast from NULL surface returned %08x\n", hr);
1769 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, NULL, 0);
1770 ok(hr == DD_OK, "BltFast from smaller to bigger surface returned %08x\n", hr);
1771 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, NULL, 0);
1772 ok(hr == DDERR_INVALIDRECT, "BltFast from bigger to smaller surface returned %08x\n", hr);
1773 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &valid, 0);
1774 ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle returned %08x\n", hr);
1775 hr = IDirectDrawSurface_BltFast(surface2, 60, 60, surface1, &valid, 0);
1776 ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
1777 hr = IDirectDrawSurface_BltFast(surface1, 90, 90, surface2, NULL, 0);
1778 ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
1780 hr = IDirectDrawSurface_BltFast(surface1, -10, 0, surface2, NULL, 0);
1781 ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
1782 hr = IDirectDrawSurface_BltFast(surface1, 0, -10, surface2, NULL, 0);
1783 ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
1784 hr = IDirectDrawSurface_BltFast(surface2, 20, 20, surface1, &valid, 0);
1785 ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle and offset returned %08x\n", hr);
1787 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid1, 0);
1788 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 1 returned %08x\n", hr);
1789 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid2, 0);
1790 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 2 returned %08x\n", hr);
1791 hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid3, 0);
1792 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
1793 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, &invalid4, 0);
1794 ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
1795 hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface1, NULL, 0);
1796 ok(hr == DD_OK, "BltFast blitting a surface onto itself returned %08x\n", hr);
1798 /* Blt(non-fast) tests */
1799 memset(&BltFx, 0, sizeof(BltFx));
1800 BltFx.dwSize = sizeof(BltFx);
1801 U5(BltFx).dwFillColor = 0xaabbccdd;
1803 hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, NULL, DDBLT_COLORFILL, &BltFx);
1804 ok(hr == DD_OK, "IDirectDrawSurface_Blt with a valid rectangle for color fill returned %08x\n", hr);
1805 hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, &invalid3, DDBLT_COLORFILL, &BltFx);
1806 ok(hr == DD_OK, "IDirectDrawSurface_Blt with an invalid, unused rectangle returned %08x\n", hr);
1807 hr = IDirectDrawSurface_Blt(surface2, &invalid1, NULL, NULL, DDBLT_COLORFILL, &BltFx);
1808 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
1809 hr = IDirectDrawSurface_Blt(surface2, &invalid2, NULL, NULL, DDBLT_COLORFILL, &BltFx);
1810 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
1811 hr = IDirectDrawSurface_Blt(surface2, &invalid3, NULL, NULL, DDBLT_COLORFILL, &BltFx);
1812 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
1813 hr = IDirectDrawSurface_Blt(surface2, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
1814 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
1816 /* Valid on surface 1 */
1817 hr = IDirectDrawSurface_Blt(surface1, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
1818 ok(hr == DD_OK, "IDirectDrawSurface_Blt with a subrectangle fill returned %08x\n", hr);
1820 /* Works - stretched blit */
1821 hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, NULL, 0, NULL);
1822 ok(hr == DD_OK, "IDirectDrawSurface_Blt from a smaller to a bigger surface returned %08x\n", hr);
1823 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, NULL, 0, NULL);
1824 ok(hr == DD_OK, "IDirectDrawSurface_Blt from a bigger to a smaller surface %08x\n", hr);
1826 /* Invalid dest rects in sourced blits */
1827 hr = IDirectDrawSurface_Blt(surface2, &invalid1, surface1, NULL, 0, NULL);
1828 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
1829 hr = IDirectDrawSurface_Blt(surface2, &invalid2, surface1, NULL, 0, NULL);
1830 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
1831 hr = IDirectDrawSurface_Blt(surface2, &invalid3, surface1, NULL, 0, NULL);
1832 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
1833 hr = IDirectDrawSurface_Blt(surface2, &invalid4, surface1, NULL, 0, NULL);
1834 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
1836 /* Invalid src rects */
1837 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid1, 0, NULL);
1838 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
1839 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid2, 0, NULL);
1840 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
1841 hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid3, 0, NULL);
1842 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
1843 hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, &invalid4, 0, NULL);
1844 ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
1846 IDirectDrawSurface_Release(surface1);
1847 IDirectDrawSurface_Release(surface2);
1850 static void PaletteTest(void)
1852 HRESULT hr;
1853 IDirectDrawSurface *lpSurf = NULL;
1854 IDirectDrawSurface *backbuffer = NULL;
1855 DDSCAPS ddscaps;
1856 DDSURFACEDESC ddsd;
1857 IDirectDrawPalette *palette = NULL;
1858 PALETTEENTRY Table[256];
1859 PALETTEENTRY palEntries[256];
1860 int i;
1862 for(i=0; i<256; i++)
1864 Table[i].peRed = 0xff;
1865 Table[i].peGreen = 0;
1866 Table[i].peBlue = 0;
1867 Table[i].peFlags = 0;
1870 /* Create a 8bit palette without DDPCAPS_ALLOW256 set */
1871 hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_8BIT, Table, &palette, NULL);
1872 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
1873 if (FAILED(hr)) goto err;
1874 /* Read back the palette and verify the entries. Without DDPCAPS_ALLOW256 set
1875 / entry 0 and 255 should have been overwritten with black and white */
1876 hr = IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
1877 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
1878 if(hr == DD_OK)
1880 ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
1881 "Palette entry 0 of a palette without DDPCAPS_ALLOW256 set should be (0,0,0) but it is (%d,%d,%d)\n",
1882 palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
1883 ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
1884 "Palette entry 255 of a palette without DDPCAPS_ALLOW256 set should be (255,255,255) but it is (%d,%d,%d)\n",
1885 palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
1887 /* Entry 1-254 should contain red */
1888 for(i=1; i<255; i++)
1889 ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
1890 "Palette entry %d should have contained (255,0,0) but was set to (%d,%d,%d)\n",
1891 i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
1894 /* CreatePalette without DDPCAPS_ALLOW256 ignores entry 0 and 255,
1895 / now check we are able to update the entries afterwards. */
1896 hr = IDirectDrawPalette_SetEntries(palette , 0, 0, 256, &Table[0]);
1897 ok(hr == DD_OK, "SetEntries failed with %08x\n", hr);
1898 hr = IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
1899 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
1900 if(hr == DD_OK)
1902 ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
1903 "Palette entry 0 should have been set to (0,0,0) but it contains (%d,%d,%d)\n",
1904 palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
1905 ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
1906 "Palette entry 255 should have been set to (255,255,255) but it contains (%d,%d,%d)\n",
1907 palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
1909 IDirectDrawPalette_Release(palette);
1911 /* Create a 8bit palette with DDPCAPS_ALLOW256 set */
1912 hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
1913 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
1914 if (FAILED(hr)) goto err;
1916 hr = IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
1917 ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
1918 if(hr == DD_OK)
1920 /* All entries should contain red */
1921 for(i=0; i<256; i++)
1922 ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
1923 "Palette entry %d should have contained (255,0,0) but was set to (%d,%d,%d)\n",
1924 i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
1927 /* Try to set palette to a non-palettized surface */
1928 ddsd.dwSize = sizeof(ddsd);
1929 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1930 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1931 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1932 ddsd.dwWidth = 800;
1933 ddsd.dwHeight = 600;
1934 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1935 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
1936 U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
1937 U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
1938 U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
1939 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurf, NULL);
1940 ok(hr==DD_OK, "CreateSurface returned: %x\n",hr);
1941 if (FAILED(hr))
1943 skip("failed to create surface\n");
1944 goto err;
1947 hr = IDirectDrawSurface_SetPalette(lpSurf, palette);
1948 ok(hr == DDERR_INVALIDPIXELFORMAT, "CreateSurface returned: %x\n",hr);
1950 IDirectDrawPalette_Release(palette);
1951 palette = NULL;
1953 hr = IDirectDrawSurface_GetPalette(lpSurf, &palette);
1954 ok(hr == DDERR_NOPALETTEATTACHED, "CreateSurface returned: %x\n",hr);
1956 err:
1958 if (lpSurf) IDirectDrawSurface_Release(lpSurf);
1959 if (palette) IDirectDrawPalette_Release(palette);
1961 hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
1962 ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
1964 ddsd.dwSize = sizeof(ddsd);
1965 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1966 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_BACKBUFFERCOUNT;
1967 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
1968 ddsd.dwWidth = 64;
1969 ddsd.dwHeight = 64;
1970 ddsd.dwBackBufferCount = 1;
1971 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
1972 U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 8;
1974 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurf, NULL);
1975 ok(hr==DD_OK, "CreateSurface returned: %x\n",hr);
1976 if (FAILED(hr))
1978 skip("failed to create surface\n");
1979 return;
1982 ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
1983 hr = IDirectDrawSurface_GetAttachedSurface(lpSurf, &ddscaps, &backbuffer);
1984 ok(hr == DD_OK, "GetAttachedSurface returned: %x\n",hr);
1986 hr = IDirectDrawSurface_SetPalette(backbuffer, palette);
1987 ok(hr == DD_OK, "SetPalette returned: %x\n",hr);
1989 IDirectDrawPalette_Release(palette);
1990 palette = NULL;
1992 hr = IDirectDrawSurface_GetPalette(backbuffer, &palette);
1993 ok(hr == DD_OK, "CreateSurface returned: %x\n",hr);
1994 IDirectDrawPalette_Release(palette);
1996 IDirectDrawSurface_Release(backbuffer);
1997 IDirectDrawSurface_Release(lpSurf);
2000 static void SurfaceCapsTest(void)
2002 DDSURFACEDESC create;
2003 DDSURFACEDESC desc;
2004 HRESULT hr;
2005 IDirectDrawSurface *surface1 = NULL;
2006 DDSURFACEDESC2 create2, desc2;
2007 IDirectDrawSurface7 *surface7 = NULL;
2008 IDirectDraw7 *dd7 = NULL;
2009 DWORD create_caps[] = {
2010 DDSCAPS_OFFSCREENPLAIN,
2011 DDSCAPS_TEXTURE,
2012 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD,
2014 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2015 DDSCAPS_PRIMARYSURFACE,
2016 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY,
2017 DDSCAPS_3DDEVICE,
2018 DDSCAPS_ZBUFFER,
2019 DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN
2021 DWORD expected_caps[] = {
2022 DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2023 DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2024 DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD,
2025 DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2026 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2027 DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_VISIBLE,
2028 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_VISIBLE,
2029 DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2030 DDSCAPS_ZBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY,
2031 DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM
2033 UINT i;
2035 /* Tests various surface flags, what changes do they undergo during
2036 * surface creation. Forsaken engine expects texture surfaces without
2037 * memory flag to get a video memory flag right after creation. */
2039 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
2041 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
2042 return ;
2045 for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2047 memset(&create, 0, sizeof(create));
2048 create.dwSize = sizeof(create);
2049 create.ddsCaps.dwCaps = create_caps[i];
2050 create.dwFlags = DDSD_CAPS;
2052 if (!(create.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2054 create.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2055 create.dwHeight = 128;
2056 create.dwWidth = 128;
2059 if (create.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
2061 create.dwFlags |= DDSD_PIXELFORMAT;
2062 create.ddpfPixelFormat.dwSize = sizeof(create.ddpfPixelFormat);
2063 create.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2064 U1(create.ddpfPixelFormat).dwZBufferBitDepth = 16;
2065 U3(create.ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
2068 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2069 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2071 if (SUCCEEDED(hr))
2073 memset(&desc, 0, sizeof(desc));
2074 desc.dwSize = sizeof(DDSURFACEDESC);
2075 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc);
2076 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2078 ok(desc.ddsCaps.dwCaps == expected_caps[i],
2079 "GetSurfaceDesc test %d returned caps %x, expected %x\n",
2080 i, desc.ddsCaps.dwCaps, expected_caps[i]);
2082 IDirectDrawSurface_Release(surface1);
2086 /* Test for differences in ddraw 7 */
2087 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2088 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
2089 if (FAILED(hr))
2091 skip("Failed to get IDirectDraw7 interface, skipping tests\n");
2093 else
2095 for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2097 memset(&create2, 0, sizeof(create2));
2098 create2.dwSize = sizeof(create2);
2099 create2.ddsCaps.dwCaps = create_caps[i];
2100 create2.dwFlags = DDSD_CAPS;
2102 if (!(create2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2104 create2.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2105 create2.dwHeight = 128;
2106 create2.dwWidth = 128;
2109 if (create2.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
2111 create2.dwFlags |= DDSD_PIXELFORMAT;
2112 U4(create2).ddpfPixelFormat.dwSize = sizeof(U4(create2).ddpfPixelFormat);
2113 U4(create2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2114 U1(U4(create2).ddpfPixelFormat).dwZBufferBitDepth = 16;
2115 U3(U4(create2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
2118 hr = IDirectDraw7_CreateSurface(dd7, &create2, &surface7, NULL);
2119 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2121 if (SUCCEEDED(hr))
2123 memset(&desc2, 0, sizeof(desc2));
2124 desc2.dwSize = sizeof(DDSURFACEDESC2);
2125 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc2);
2126 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2128 ok(desc2.ddsCaps.dwCaps == expected_caps[i],
2129 "GetSurfaceDesc test %d returned caps %x, expected %x\n",
2130 i, desc2.ddsCaps.dwCaps, expected_caps[i]);
2132 IDirectDrawSurface7_Release(surface7);
2136 IDirectDraw7_Release(dd7);
2139 memset(&create, 0, sizeof(create));
2140 create.dwSize = sizeof(create);
2141 create.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2142 create.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY;
2143 create.dwWidth = 64;
2144 create.dwHeight = 64;
2145 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2146 ok(hr == DDERR_INVALIDCAPS, "Creating a SYSMEM | VIDMEM surface returned 0x%08x, expected DDERR_INVALIDCAPS\n", hr);
2147 if(surface1) IDirectDrawSurface_Release(surface1);
2150 static BOOL can_create_primary_surface(void)
2152 DDSURFACEDESC ddsd;
2153 IDirectDrawSurface *surface;
2154 HRESULT hr;
2156 memset(&ddsd, 0, sizeof(ddsd));
2157 ddsd.dwSize = sizeof(ddsd);
2158 ddsd.dwFlags = DDSD_CAPS;
2159 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2160 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2161 if(FAILED(hr)) return FALSE;
2162 IDirectDrawSurface_Release(surface);
2163 return TRUE;
2166 static void BackBufferCreateSurfaceTest(void)
2168 DDSURFACEDESC ddsd;
2169 DDSURFACEDESC created_ddsd;
2170 DDSURFACEDESC2 ddsd2;
2171 IDirectDrawSurface *surf;
2172 IDirectDrawSurface4 *surf4;
2173 IDirectDrawSurface7 *surf7;
2174 HRESULT hr;
2175 IDirectDraw2 *dd2;
2176 IDirectDraw4 *dd4;
2177 IDirectDraw7 *dd7;
2179 const DWORD caps = DDSCAPS_BACKBUFFER;
2180 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
2182 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
2184 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
2185 return ;
2188 memset(&ddsd, 0, sizeof(ddsd));
2189 ddsd.dwSize = sizeof(ddsd);
2190 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2191 ddsd.dwWidth = 64;
2192 ddsd.dwHeight = 64;
2193 ddsd.ddsCaps.dwCaps = caps;
2194 memset(&ddsd2, 0, sizeof(ddsd2));
2195 ddsd2.dwSize = sizeof(ddsd2);
2196 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2197 ddsd2.dwWidth = 64;
2198 ddsd2.dwHeight = 64;
2199 ddsd2.ddsCaps.dwCaps = caps;
2200 memset(&created_ddsd, 0, sizeof(created_ddsd));
2201 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
2203 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
2204 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
2205 if (surf != NULL)
2207 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
2208 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
2209 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
2210 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
2211 expected_caps);
2212 IDirectDrawSurface_Release(surf);
2215 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
2216 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2218 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
2219 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
2220 DDERR_INVALIDCAPS, hr);
2222 IDirectDraw2_Release(dd2);
2224 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
2225 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2227 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
2228 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
2229 DDERR_INVALIDCAPS, hr);
2231 IDirectDraw4_Release(dd4);
2233 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2234 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2236 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
2237 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
2238 DDERR_INVALIDCAPS, hr);
2240 IDirectDraw7_Release(dd7);
2243 static void BackBufferAttachmentFlipTest(void)
2245 HRESULT hr;
2246 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
2247 DDSURFACEDESC ddsd;
2248 HWND window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
2249 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2251 hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2252 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
2254 /* Perform attachment tests on a back-buffer */
2255 memset(&ddsd, 0, sizeof(ddsd));
2256 ddsd.dwSize = sizeof(ddsd);
2257 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2258 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
2259 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
2260 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
2261 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
2262 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
2264 if (surface2 != NULL)
2266 /* Try a single primary and a two back buffers */
2267 memset(&ddsd, 0, sizeof(ddsd));
2268 ddsd.dwSize = sizeof(ddsd);
2269 ddsd.dwFlags = DDSD_CAPS;
2270 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2271 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
2272 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2274 memset(&ddsd, 0, sizeof(ddsd));
2275 ddsd.dwSize = sizeof(ddsd);
2276 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2277 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
2278 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
2279 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
2280 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
2281 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2283 /* This one has a different size */
2284 memset(&ddsd, 0, sizeof(ddsd));
2285 ddsd.dwSize = sizeof(ddsd);
2286 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2287 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
2288 ddsd.dwWidth = 128;
2289 ddsd.dwHeight = 128;
2290 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
2291 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2293 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
2294 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
2295 "Attaching a back buffer to a front buffer returned %08x\n", hr);
2296 if(SUCCEEDED(hr))
2298 /* Try flipping the surfaces */
2299 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
2300 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2301 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
2302 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2304 /* Try the reverse without detaching first */
2305 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
2306 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
2307 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
2308 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
2310 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
2311 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
2312 "Attaching a front buffer to a back buffer returned %08x\n", hr);
2313 if(SUCCEEDED(hr))
2315 /* Try flipping the surfaces */
2316 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
2317 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2318 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
2319 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2321 /* Try to detach reversed */
2322 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
2323 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
2324 /* Now the proper detach */
2325 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
2326 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
2328 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
2329 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
2330 "Attaching a back buffer to another back buffer returned %08x\n", hr);
2331 if(SUCCEEDED(hr))
2333 /* Try flipping the surfaces */
2334 hr = IDirectDrawSurface_Flip(surface3, NULL, DDFLIP_WAIT);
2335 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2336 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
2337 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2338 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
2339 ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2341 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
2342 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
2344 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
2345 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
2346 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
2347 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
2349 IDirectDrawSurface_Release(surface4);
2350 IDirectDrawSurface_Release(surface3);
2351 IDirectDrawSurface_Release(surface2);
2352 IDirectDrawSurface_Release(surface1);
2355 hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
2356 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
2358 DestroyWindow(window);
2361 static void CreateSurfaceBadCapsSizeTest(void)
2363 DDSURFACEDESC ddsd_ok;
2364 DDSURFACEDESC ddsd_bad1;
2365 DDSURFACEDESC ddsd_bad2;
2366 DDSURFACEDESC ddsd_bad3;
2367 DDSURFACEDESC ddsd_bad4;
2368 DDSURFACEDESC2 ddsd2_ok;
2369 DDSURFACEDESC2 ddsd2_bad1;
2370 DDSURFACEDESC2 ddsd2_bad2;
2371 DDSURFACEDESC2 ddsd2_bad3;
2372 DDSURFACEDESC2 ddsd2_bad4;
2373 IDirectDrawSurface *surf;
2374 IDirectDrawSurface4 *surf4;
2375 IDirectDrawSurface7 *surf7;
2376 HRESULT hr;
2377 IDirectDraw2 *dd2;
2378 IDirectDraw4 *dd4;
2379 IDirectDraw7 *dd7;
2381 const DWORD caps = DDSCAPS_OFFSCREENPLAIN;
2383 memset(&ddsd_ok, 0, sizeof(ddsd_ok));
2384 ddsd_ok.dwSize = sizeof(ddsd_ok);
2385 ddsd_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2386 ddsd_ok.dwWidth = 64;
2387 ddsd_ok.dwHeight = 64;
2388 ddsd_ok.ddsCaps.dwCaps = caps;
2389 ddsd_bad1 = ddsd_ok;
2390 ddsd_bad1.dwSize--;
2391 ddsd_bad2 = ddsd_ok;
2392 ddsd_bad2.dwSize++;
2393 ddsd_bad3 = ddsd_ok;
2394 ddsd_bad3.dwSize = 0;
2395 ddsd_bad4 = ddsd_ok;
2396 ddsd_bad4.dwSize = sizeof(DDSURFACEDESC2);
2398 memset(&ddsd2_ok, 0, sizeof(ddsd2_ok));
2399 ddsd2_ok.dwSize = sizeof(ddsd2_ok);
2400 ddsd2_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2401 ddsd2_ok.dwWidth = 64;
2402 ddsd2_ok.dwHeight = 64;
2403 ddsd2_ok.ddsCaps.dwCaps = caps;
2404 ddsd2_bad1 = ddsd2_ok;
2405 ddsd2_bad1.dwSize--;
2406 ddsd2_bad2 = ddsd2_ok;
2407 ddsd2_bad2.dwSize++;
2408 ddsd2_bad3 = ddsd2_ok;
2409 ddsd2_bad3.dwSize = 0;
2410 ddsd2_bad4 = ddsd2_ok;
2411 ddsd2_bad4.dwSize = sizeof(DDSURFACEDESC);
2413 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_ok, &surf, NULL);
2414 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
2415 IDirectDrawSurface_Release(surf);
2417 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad1, &surf, NULL);
2418 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2419 DDERR_INVALIDPARAMS, hr);
2420 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad2, &surf, NULL);
2421 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2422 DDERR_INVALIDPARAMS, hr);
2423 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad3, &surf, NULL);
2424 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2425 DDERR_INVALIDPARAMS, hr);
2426 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad4, &surf, NULL);
2427 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2428 DDERR_INVALIDPARAMS, hr);
2429 hr = IDirectDraw_CreateSurface(lpDD, NULL, &surf, NULL);
2430 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2431 DDERR_INVALIDPARAMS, hr);
2433 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
2434 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2436 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_ok, &surf, NULL);
2437 ok(SUCCEEDED(hr), "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
2438 IDirectDrawSurface_Release(surf);
2440 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad1, &surf, NULL);
2441 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2442 DDERR_INVALIDPARAMS, hr);
2443 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad2, &surf, NULL);
2444 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2445 DDERR_INVALIDPARAMS, hr);
2446 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad3, &surf, NULL);
2447 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2448 DDERR_INVALIDPARAMS, hr);
2449 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad4, &surf, NULL);
2450 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2451 DDERR_INVALIDPARAMS, hr);
2452 hr = IDirectDraw2_CreateSurface(dd2, NULL, &surf, NULL);
2453 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2454 DDERR_INVALIDPARAMS, hr);
2456 IDirectDraw2_Release(dd2);
2458 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
2459 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2461 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_ok, &surf4, NULL);
2462 ok(SUCCEEDED(hr), "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
2463 IDirectDrawSurface4_Release(surf4);
2465 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad1, &surf4, NULL);
2466 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2467 DDERR_INVALIDPARAMS, hr);
2468 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad2, &surf4, NULL);
2469 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2470 DDERR_INVALIDPARAMS, hr);
2471 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad3, &surf4, NULL);
2472 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2473 DDERR_INVALIDPARAMS, hr);
2474 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad4, &surf4, NULL);
2475 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2476 DDERR_INVALIDPARAMS, hr);
2477 hr = IDirectDraw4_CreateSurface(dd4, NULL, &surf4, NULL);
2478 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2479 DDERR_INVALIDPARAMS, hr);
2481 IDirectDraw4_Release(dd4);
2483 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2484 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2486 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_ok, &surf7, NULL);
2487 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
2488 IDirectDrawSurface7_Release(surf7);
2490 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad1, &surf7, NULL);
2491 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2492 DDERR_INVALIDPARAMS, hr);
2493 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad2, &surf7, NULL);
2494 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2495 DDERR_INVALIDPARAMS, hr);
2496 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad3, &surf7, NULL);
2497 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2498 DDERR_INVALIDPARAMS, hr);
2499 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad4, &surf7, NULL);
2500 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2501 DDERR_INVALIDPARAMS, hr);
2502 hr = IDirectDraw7_CreateSurface(dd7, NULL, &surf7, NULL);
2503 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2504 DDERR_INVALIDPARAMS, hr);
2506 IDirectDraw7_Release(dd7);
2509 static void reset_ddsd(DDSURFACEDESC *ddsd)
2511 memset(ddsd, 0, sizeof(*ddsd));
2512 ddsd->dwSize = sizeof(*ddsd);
2515 static void no_ddsd_caps_test(void)
2517 DDSURFACEDESC ddsd;
2518 HRESULT hr;
2519 IDirectDrawSurface *surface;
2521 reset_ddsd(&ddsd);
2522 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
2523 ddsd.dwWidth = 128;
2524 ddsd.dwHeight = 128;
2525 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2526 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2527 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
2528 reset_ddsd(&ddsd);
2529 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
2530 IDirectDrawSurface_Release(surface);
2531 ok(ddsd.dwFlags & DDSD_CAPS, "DDSD_CAPS is not set\n");
2532 ok(ddsd.ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN, "DDSCAPS_OFFSCREENPLAIN is not set\n");
2534 reset_ddsd(&ddsd);
2535 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2536 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2537 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
2538 reset_ddsd(&ddsd);
2539 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
2540 IDirectDrawSurface_Release(surface);
2541 ok(ddsd.dwFlags & DDSD_CAPS, "DDSD_CAPS is not set\n");
2542 ok(ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE, "DDSCAPS_OFFSCREENPLAIN is not set\n");
2544 reset_ddsd(&ddsd);
2545 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
2546 ddsd.dwWidth = 128;
2547 ddsd.dwHeight = 128;
2548 ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
2549 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2550 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw_CreateSurface returned %#x, expected DDERR_INVALIDCAPS.\n", hr);
2553 static void dump_format(const DDPIXELFORMAT *fmt)
2555 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %u\n", fmt->dwFlags, fmt->dwFourCC,
2556 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
2557 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
2558 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
2561 static void zbufferbitdepth_test(void)
2563 enum zfmt_succeed
2565 ZFMT_SUPPORTED_ALWAYS,
2566 ZFMT_SUPPORTED_NEVER,
2567 ZFMT_SUPPORTED_HWDEPENDENT
2569 struct
2571 DWORD depth;
2572 enum zfmt_succeed supported;
2573 DDPIXELFORMAT pf;
2575 test_data[] =
2578 16, ZFMT_SUPPORTED_ALWAYS,
2580 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
2581 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
2585 24, ZFMT_SUPPORTED_HWDEPENDENT,
2587 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
2588 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
2592 32, ZFMT_SUPPORTED_HWDEPENDENT,
2594 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
2595 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
2598 /* Returns DDERR_INVALIDPARAMS instead of DDERR_INVALIDPIXELFORMAT.
2599 * Disabled for now
2601 0, ZFMT_SUPPORTED_NEVER
2605 15, ZFMT_SUPPORTED_NEVER
2608 28, ZFMT_SUPPORTED_NEVER
2611 40, ZFMT_SUPPORTED_NEVER
2615 DDSURFACEDESC ddsd;
2616 IDirectDrawSurface *surface;
2617 HRESULT hr;
2618 unsigned int i;
2619 DDCAPS caps;
2621 memset(&caps, 0, sizeof(caps));
2622 caps.dwSize = sizeof(caps);
2623 hr = IDirectDraw_GetCaps(lpDD, &caps, NULL);
2624 ok(SUCCEEDED(hr), "IDirectDraw_GetCaps failed, hr %#x.\n", hr);
2625 if (!(caps.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
2627 skip("Z buffers not supported, skipping DDSD_ZBUFFERBITDEPTH test\n");
2628 return;
2631 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
2633 reset_ddsd(&ddsd);
2634 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH;
2635 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
2636 ddsd.dwWidth = 256;
2637 ddsd.dwHeight = 256;
2638 U2(ddsd).dwZBufferBitDepth = test_data[i].depth;
2640 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2641 if (test_data[i].supported == ZFMT_SUPPORTED_ALWAYS)
2643 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
2645 else if (test_data[i].supported == ZFMT_SUPPORTED_NEVER)
2647 ok(hr == DDERR_INVALIDPIXELFORMAT, "IDirectDraw_CreateSurface returned %#x, expected %x.\n",
2648 hr, DDERR_INVALIDPIXELFORMAT);
2650 if (!surface) continue;
2652 reset_ddsd(&ddsd);
2653 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
2654 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
2655 IDirectDrawSurface_Release(surface);
2657 ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
2658 ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
2659 /* Yet the ddpfPixelFormat member contains valid data */
2660 if (memcmp(&ddsd.ddpfPixelFormat, &test_data[i].pf, ddsd.ddpfPixelFormat.dwSize))
2662 ok(0, "Unexpected format for depth %u\n", test_data[i].depth);
2663 dump_format(&ddsd.ddpfPixelFormat);
2667 /* DDSD_ZBUFFERBITDEPTH vs DDSD_PIXELFORMAT? */
2668 reset_ddsd(&ddsd);
2669 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_ZBUFFERBITDEPTH;
2670 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
2671 ddsd.dwWidth = 256;
2672 ddsd.dwHeight = 256;
2673 U2(ddsd).dwZBufferBitDepth = 24;
2674 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2675 ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2676 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth = 16;
2677 U3(ddsd.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
2679 surface = NULL;
2680 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2681 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
2682 if (!surface) return;
2683 reset_ddsd(&ddsd);
2684 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
2685 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
2686 IDirectDrawSurface_Release(surface);
2687 ok(U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth == 16, "Expected a 16bpp depth buffer, got %ubpp\n",
2688 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth);
2689 ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
2690 ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
2691 ok(U2(ddsd).dwZBufferBitDepth == 16, "Expected dwZBufferBitDepth=16, got %u\n",
2692 U2(ddsd).dwZBufferBitDepth);
2694 /* DDSD_PIXELFORMAT vs invalid ZBUFFERBITDEPTH */
2695 reset_ddsd(&ddsd);
2696 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_PIXELFORMAT;
2697 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
2698 ddsd.dwWidth = 256;
2699 ddsd.dwHeight = 256;
2700 U2(ddsd).dwZBufferBitDepth = 40;
2701 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2702 ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2703 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth = 16;
2704 U3(ddsd.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
2705 surface = NULL;
2706 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2707 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
2708 if (surface) IDirectDrawSurface_Release(surface);
2710 /* Create a PIXELFORMAT-only surface, see if ZBUFFERBITDEPTH is set */
2711 reset_ddsd(&ddsd);
2712 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
2713 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
2714 ddsd.dwWidth = 256;
2715 ddsd.dwHeight = 256;
2716 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2717 ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2718 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth = 16;
2719 U3(ddsd.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
2720 surface = NULL;
2721 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2722 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
2723 reset_ddsd(&ddsd);
2724 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
2725 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
2726 IDirectDrawSurface_Release(surface);
2727 ok(U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth == 16, "Expected a 16bpp depth buffer, got %ubpp\n",
2728 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth);
2729 ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
2730 ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
2731 ok(U2(ddsd).dwZBufferBitDepth == 16, "Expected dwZBufferBitDepth=16, got %u\n",
2732 U2(ddsd).dwZBufferBitDepth);
2735 static void test_ddsd(DDSURFACEDESC *ddsd, BOOL expect_pf, BOOL expect_zd, const char *name, DWORD z_bit_depth)
2737 IDirectDrawSurface *surface;
2738 IDirectDrawSurface7 *surface7;
2739 HRESULT hr;
2740 DDSURFACEDESC out;
2741 DDSURFACEDESC2 out2;
2743 hr = IDirectDraw_CreateSurface(lpDD, ddsd, &surface, NULL);
2744 if (hr == DDERR_NOZBUFFERHW)
2746 skip("Z buffers not supported, skipping Z flag test\n");
2747 return;
2749 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
2750 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **) &surface7);
2751 ok(SUCCEEDED(hr), "IDirectDrawSurface_QueryInterface failed, hr %#x.\n", hr);
2753 reset_ddsd(&out);
2754 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &out);
2755 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
2756 memset(&out2, 0, sizeof(out2));
2757 out2.dwSize = sizeof(out2);
2758 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &out2);
2759 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
2761 if (expect_pf)
2763 ok(out.dwFlags & DDSD_PIXELFORMAT, "%s surface: Expected DDSD_PIXELFORMAT to be set\n", name);
2764 ok(out2.dwFlags & DDSD_PIXELFORMAT,
2765 "%s surface: Expected DDSD_PIXELFORMAT to be set in DDSURFACEDESC2\n", name);
2767 else
2769 ok(!(out.dwFlags & DDSD_PIXELFORMAT), "%s surface: Expected DDSD_PIXELFORMAT not to be set\n", name);
2770 ok(out2.dwFlags & DDSD_PIXELFORMAT,
2771 "%s surface: Expected DDSD_PIXELFORMAT to be set in DDSURFACEDESC2\n", name);
2773 if (expect_zd)
2775 ok(out.dwFlags & DDSD_ZBUFFERBITDEPTH, "%s surface: Expected DDSD_ZBUFFERBITDEPTH to be set\n", name);
2776 ok(U2(out).dwZBufferBitDepth == z_bit_depth, "ZBufferBitDepth is %u, expected %u\n",
2777 U2(out).dwZBufferBitDepth, z_bit_depth);
2778 ok(!(out2.dwFlags & DDSD_ZBUFFERBITDEPTH),
2779 "%s surface: Did not expect DDSD_ZBUFFERBITDEPTH to be set in DDSURFACEDESC2\n", name);
2780 /* dwMipMapCount and dwZBufferBitDepth share the same union */
2781 ok(U2(out2).dwMipMapCount == 0, "dwMipMapCount is %u, expected 0\n", U2(out2).dwMipMapCount);
2783 else
2785 ok(!(out.dwFlags & DDSD_ZBUFFERBITDEPTH), "%s surface: Expected DDSD_ZBUFFERBITDEPTH not to be set\n", name);
2786 ok(U2(out).dwZBufferBitDepth == 0, "ZBufferBitDepth is %u, expected 0\n", U2(out).dwZBufferBitDepth);
2787 ok(!(out2.dwFlags & DDSD_ZBUFFERBITDEPTH),
2788 "%s surface: Did not expect DDSD_ZBUFFERBITDEPTH to be set in DDSURFACEDESC2\n", name);
2789 ok(U2(out2).dwMipMapCount == 0, "dwMipMapCount is %u, expected 0\n", U2(out2).dwMipMapCount);
2792 reset_ddsd(&out);
2793 hr = IDirectDrawSurface_Lock(surface, NULL, &out, 0, NULL);
2794 if (SUCCEEDED(hr))
2796 hr = IDirectDrawSurface_Unlock(surface, NULL);
2797 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
2799 /* DDSD_ZBUFFERBITDEPTH is never set on Nvidia, but follows GetSurfaceDesc rules on AMD */
2800 if (!expect_zd)
2802 ok(!(out.dwFlags & DDSD_ZBUFFERBITDEPTH),
2803 "Lock %s surface: Expected DDSD_ZBUFFERBITDEPTH not to be set\n", name);
2806 /* DDSD_PIXELFORMAT follows GetSurfaceDesc rules */
2807 if (expect_pf)
2809 ok(out.dwFlags & DDSD_PIXELFORMAT, "%s surface: Expected DDSD_PIXELFORMAT to be set\n", name);
2811 else
2813 ok(!(out.dwFlags & DDSD_PIXELFORMAT),
2814 "Lock %s surface: Expected DDSD_PIXELFORMAT not to be set\n", name);
2816 if (out.dwFlags & DDSD_ZBUFFERBITDEPTH)
2817 ok(U2(out).dwZBufferBitDepth == z_bit_depth, "ZBufferBitDepth is %u, expected %u\n",
2818 U2(out).dwZBufferBitDepth, z_bit_depth);
2819 else
2820 ok(U2(out).dwZBufferBitDepth == 0, "ZBufferBitDepth is %u, expected 0\n", U2(out).dwZBufferBitDepth);
2823 hr = IDirectDrawSurface7_Lock(surface7, NULL, &out2, 0, NULL);
2824 ok(SUCCEEDED(hr), "IDirectDrawSurface7_Lock failed, hr %#x.\n", hr);
2825 if (SUCCEEDED(hr))
2827 hr = IDirectDrawSurface7_Unlock(surface7, NULL);
2828 ok(SUCCEEDED(hr), "IDirectDrawSurface7_Unlock failed, hr %#x.\n", hr);
2829 /* DDSD_PIXELFORMAT is always set, DDSD_ZBUFFERBITDEPTH never */
2830 ok(out2.dwFlags & DDSD_PIXELFORMAT,
2831 "Lock %s surface: Expected DDSD_PIXELFORMAT to be set in DDSURFACEDESC2\n", name);
2832 ok(!(out2.dwFlags & DDSD_ZBUFFERBITDEPTH),
2833 "Lock %s surface: Did not expect DDSD_ZBUFFERBITDEPTH to be set in DDSURFACEDESC2\n", name);
2834 ok(U2(out2).dwMipMapCount == 0, "dwMipMapCount is %u, expected 0\n", U2(out2).dwMipMapCount);
2837 IDirectDrawSurface7_Release(surface7);
2838 IDirectDrawSurface_Release(surface);
2841 static void pixelformat_flag_test(void)
2843 DDSURFACEDESC ddsd;
2844 DDCAPS caps;
2845 HRESULT hr;
2847 memset(&caps, 0, sizeof(caps));
2848 caps.dwSize = sizeof(caps);
2849 hr = IDirectDraw_GetCaps(lpDD, &caps, NULL);
2850 ok(SUCCEEDED(hr), "IDirectDraw_GetCaps failed, hr %#x.\n", hr);
2851 if (!(caps.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
2853 skip("Z buffers not supported, skipping DDSD_PIXELFORMAT test\n");
2854 return;
2857 reset_ddsd(&ddsd);
2858 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2859 ddsd.dwWidth = 64;
2860 ddsd.dwHeight = 64;
2861 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2862 test_ddsd(&ddsd, TRUE, FALSE, "offscreen plain", ~0U);
2864 reset_ddsd(&ddsd);
2865 ddsd.dwFlags = DDSD_CAPS;
2866 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2867 test_ddsd(&ddsd, TRUE, FALSE, "primary", ~0U);
2869 reset_ddsd(&ddsd);
2870 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_ZBUFFERBITDEPTH;
2871 ddsd.dwWidth = 64;
2872 ddsd.dwHeight = 64;
2873 U2(ddsd).dwZBufferBitDepth = 16;
2874 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
2875 test_ddsd(&ddsd, FALSE, TRUE, "Z buffer", 16);
2878 static BOOL fourcc_supported(DWORD fourcc, DWORD caps)
2880 DDSURFACEDESC ddsd;
2881 HRESULT hr;
2882 IDirectDrawSurface *surface;
2884 reset_ddsd(&ddsd);
2885 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2886 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
2887 ddsd.dwWidth = 4;
2888 ddsd.dwHeight = 4;
2889 ddsd.ddsCaps.dwCaps = caps;
2890 ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
2891 ddsd.ddpfPixelFormat.dwFourCC = fourcc;
2892 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2893 if (FAILED(hr))
2895 return FALSE;
2897 IDirectDrawSurface_Release(surface);
2898 return TRUE;
2901 static void partial_block_lock_test(void)
2903 IDirectDrawSurface7 *surface;
2904 HRESULT hr;
2905 DDSURFACEDESC2 ddsd;
2906 IDirectDraw7 *dd7;
2907 const struct
2909 DWORD caps, caps2;
2910 const char *name;
2911 BOOL success;
2913 pools[] =
2916 DDSCAPS_VIDEOMEMORY, 0,
2917 "D3DPOOL_DEFAULT", FALSE
2920 DDSCAPS_SYSTEMMEMORY, 0,
2921 "D3DPOOL_SYSTEMMEM", TRUE
2924 0, DDSCAPS2_TEXTUREMANAGE,
2925 "D3DPOOL_MANAGED", TRUE
2928 const struct
2930 DWORD fourcc;
2931 DWORD caps;
2932 const char *name;
2933 unsigned int block_width;
2934 unsigned int block_height;
2936 formats[] =
2938 {MAKEFOURCC('D','X','T','1'), DDSCAPS_TEXTURE, "D3DFMT_DXT1", 4, 4},
2939 {MAKEFOURCC('D','X','T','2'), DDSCAPS_TEXTURE, "D3DFMT_DXT2", 4, 4},
2940 {MAKEFOURCC('D','X','T','3'), DDSCAPS_TEXTURE, "D3DFMT_DXT3", 4, 4},
2941 {MAKEFOURCC('D','X','T','4'), DDSCAPS_TEXTURE, "D3DFMT_DXT4", 4, 4},
2942 {MAKEFOURCC('D','X','T','5'), DDSCAPS_TEXTURE, "D3DFMT_DXT5", 4, 4},
2943 /* ATI2N surfaces aren't available in ddraw */
2944 {MAKEFOURCC('U','Y','V','Y'), DDSCAPS_OVERLAY, "D3DFMT_UYVY", 2, 1},
2945 {MAKEFOURCC('Y','U','Y','2'), DDSCAPS_OVERLAY, "D3DFMT_YUY2", 2, 1},
2947 unsigned int i, j;
2948 RECT rect;
2950 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2951 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
2953 for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
2955 if (!fourcc_supported(formats[i].fourcc, formats[i].caps | DDSCAPS_VIDEOMEMORY))
2957 skip("%s surfaces not supported, skipping partial block lock test\n", formats[i].name);
2958 continue;
2961 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); j++)
2963 if (formats[i].caps & DDSCAPS_OVERLAY && !(pools[j].caps & DDSCAPS_VIDEOMEMORY))
2964 continue;
2966 memset(&ddsd, 0, sizeof(ddsd));
2967 ddsd.dwSize = sizeof(ddsd);
2968 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
2969 ddsd.dwWidth = 128;
2970 ddsd.dwHeight = 128;
2971 ddsd.ddsCaps.dwCaps = pools[j].caps | formats[i].caps;
2972 ddsd.ddsCaps.dwCaps2 = pools[j].caps2;
2973 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
2974 U4(ddsd).ddpfPixelFormat.dwFourCC = formats[i].fourcc;
2975 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2976 ok(SUCCEEDED(hr), "CreateSurface failed, hr %#x, format %s, pool %s\n",
2977 hr, formats[i].name, pools[j].name);
2979 /* All Windows versions allow partial block locks with DDSCAPS_SYSTEMMEMORY and
2980 * DDSCAPS2_TEXTUREMANAGE, just like in d3d8 and d3d9. Windows XP also allows those locks
2981 * with DDSCAPS_VIDEOMEMORY. Windows Vista and Windows 7 disallow partial locks of vidmem
2982 * surfaces, making the ddraw behavior consistent with d3d8 and 9.
2984 * Mark the Windows XP behavior as broken until we find an application that needs it */
2985 if (formats[i].block_width > 1)
2987 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
2988 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
2989 ok(SUCCEEDED(hr) == pools[j].success || broken(SUCCEEDED(hr)),
2990 "Partial block lock %s, expected %s, format %s, pool %s\n",
2991 SUCCEEDED(hr) ? "succeeded" : "failed", pools[j].success ? "success" : "failure",
2992 formats[i].name, pools[j].name);
2993 if (SUCCEEDED(hr))
2995 hr = IDirectDrawSurface7_Unlock(surface, NULL);
2996 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
2999 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
3000 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3001 ok(SUCCEEDED(hr) == pools[j].success || broken(SUCCEEDED(hr)),
3002 "Partial block lock %s, expected %s, format %s, pool %s\n",
3003 SUCCEEDED(hr) ? "succeeded" : "failed", pools[j].success ? "success" : "failure",
3004 formats[i].name, pools[j].name);
3005 if (SUCCEEDED(hr))
3007 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3008 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3012 if (formats[i].block_height > 1)
3014 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
3015 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3016 ok(SUCCEEDED(hr) == pools[j].success || broken(SUCCEEDED(hr)),
3017 "Partial block lock %s, expected %s, format %s, pool %s\n",
3018 SUCCEEDED(hr) ? "succeeded" : "failed", pools[j].success ? "success" : "failure",
3019 formats[i].name, pools[j].name);
3020 if (SUCCEEDED(hr))
3022 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3023 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3026 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
3027 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3028 ok(SUCCEEDED(hr) == pools[j].success || broken(SUCCEEDED(hr)),
3029 "Partial block lock %s, expected %s, format %s, pool %s\n",
3030 SUCCEEDED(hr) ? "succeeded" : "failed", pools[j].success ? "success" : "failure",
3031 formats[i].name, pools[j].name);
3032 if (SUCCEEDED(hr))
3034 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3035 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3039 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
3040 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3041 ok(SUCCEEDED(hr), "Full block lock returned %08x, expected %08x, format %s, pool %s\n",
3042 hr, DD_OK, formats[i].name, pools[j].name);
3043 if (SUCCEEDED(hr))
3045 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3046 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3049 IDirectDrawSurface7_Release(surface);
3053 IDirectDraw7_Release(dd7);
3056 static void create_surface_test(void)
3058 HRESULT hr;
3059 IDirectDraw2 *ddraw2;
3060 IDirectDraw4 *ddraw4;
3061 IDirectDraw7 *ddraw7;
3062 IDirectDrawSurface *surface;
3063 IDirectDrawSurface4 *surface4;
3064 IDirectDrawSurface7 *surface7;
3066 hr = IDirectDraw_CreateSurface(lpDD, NULL, &surface, NULL);
3067 ok(hr == DDERR_INVALIDPARAMS, "CreateSurface(ddsd=NULL) returned %#x,"
3068 " expected %#x.\n", hr, DDERR_INVALIDPARAMS);
3070 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &ddraw2);
3071 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3073 hr = IDirectDraw2_CreateSurface(ddraw2, NULL, &surface, NULL);
3074 ok(hr == DDERR_INVALIDPARAMS, "CreateSurface(ddsd=NULL) returned %#x,"
3075 " expected %#x.\n", hr, DDERR_INVALIDPARAMS);
3077 IDirectDraw2_Release(ddraw2);
3079 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &ddraw4);
3080 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3082 hr = IDirectDraw4_CreateSurface(ddraw4, NULL, &surface4, NULL);
3083 ok(hr == DDERR_INVALIDPARAMS, "CreateSurface(ddsd=NULL) returned %#x,"
3084 " expected %#x.\n", hr, DDERR_INVALIDPARAMS);
3086 IDirectDraw4_Release(ddraw4);
3088 if (!pDirectDrawCreateEx)
3090 skip("DirectDrawCreateEx not available, skipping IDirectDraw7 tests.\n");
3091 return;
3093 hr = pDirectDrawCreateEx(NULL, (void **) &ddraw7, &IID_IDirectDraw7, NULL);
3094 ok(SUCCEEDED(hr), "DirectDrawCreateEx failed, hr %#x.\n", hr);
3096 hr = IDirectDraw7_CreateSurface(ddraw7, NULL, &surface7, NULL);
3097 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "CreateSurface(ddsd=NULL, pre-SCL) returned %#x,"
3098 " expected %#x.\n", hr, DDERR_NOCOOPERATIVELEVELSET);
3100 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, NULL, DDSCL_NORMAL);
3101 ok(hr == DD_OK, "SetCooperativeLevel failed, hr %#x.\n", hr);
3103 hr = IDirectDraw7_CreateSurface(ddraw7, NULL, &surface7, NULL);
3104 ok(hr == DDERR_INVALIDPARAMS, "CreateSurface(ddsd=NULL) returned %#x,"
3105 " expected %#x.\n", hr, DDERR_INVALIDPARAMS);
3107 IDirectDraw7_Release(ddraw7);
3110 START_TEST(dsurface)
3112 HRESULT ret;
3113 IDirectDraw4 *dd4;
3115 HMODULE ddraw_mod = GetModuleHandleA("ddraw.dll");
3116 pDirectDrawCreateEx = (void *) GetProcAddress(ddraw_mod, "DirectDrawCreateEx");
3118 if (!CreateDirectDraw())
3119 return;
3121 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3122 if (ret == E_NOINTERFACE)
3124 win_skip("DirectDraw4 and higher are not supported\n");
3125 ReleaseDirectDraw();
3126 return;
3128 IDirectDraw_Release(dd4);
3130 if(!can_create_primary_surface())
3132 skip("Unable to create primary surface\n");
3133 return;
3136 ddcaps.dwSize = sizeof(DDCAPS);
3137 ret = IDirectDraw_GetCaps(lpDD, &ddcaps, NULL);
3138 if (ret != DD_OK)
3140 skip("IDirectDraw_GetCaps failed with %08x\n", ret);
3141 return;
3144 SrcColorKey32BlitTest();
3145 QueryInterface();
3146 GetDDInterface_1();
3147 GetDDInterface_2();
3148 GetDDInterface_4();
3149 GetDDInterface_7();
3150 EnumTest();
3151 CubeMapTest();
3152 CompressedTest();
3153 SizeTest();
3154 BltParamTest();
3155 PaletteTest();
3156 SurfaceCapsTest();
3157 BackBufferCreateSurfaceTest();
3158 BackBufferAttachmentFlipTest();
3159 CreateSurfaceBadCapsSizeTest();
3160 no_ddsd_caps_test();
3161 zbufferbitdepth_test();
3162 pixelformat_flag_test();
3163 partial_block_lock_test();
3164 create_surface_test();
3165 ReleaseDirectDraw();