ddraw/tests: Test matrices in TransformVertices.
[wine.git] / dlls / ddraw / tests / dsurface.c
blob2efb23aa7ebbfa2c5dc6507a2d9a20bed42d19d2
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 StructSizeTest(void)
2002 IDirectDrawSurface *surface1;
2003 IDirectDrawSurface7 *surface7;
2004 union {
2005 DDSURFACEDESC desc1;
2006 DDSURFACEDESC2 desc2;
2007 char blob[1024]; /* To get a bunch of writable memory */
2008 } desc;
2009 DDSURFACEDESC create;
2010 HRESULT hr;
2012 memset(&desc, 0, sizeof(desc));
2013 memset(&create, 0, sizeof(create));
2015 memset(&create, 0, sizeof(create));
2016 create.dwSize = sizeof(create);
2017 create.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2018 create.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2019 create.dwHeight = 128;
2020 create.dwWidth = 128;
2021 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2022 ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2023 hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface7, (void **) &surface7);
2024 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2026 desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2027 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2028 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2029 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2030 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2032 desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2033 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2034 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2035 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2036 ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2038 desc.desc2.dwSize = 0;
2039 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2040 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2041 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2042 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2044 desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2045 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2046 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2047 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2048 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2050 desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2051 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2052 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2053 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2054 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2056 /* Tests for Lock() */
2058 desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2059 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2060 ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2061 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2062 ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2063 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2064 ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2065 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2066 ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2068 desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2069 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2070 ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2071 ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2072 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2073 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2074 ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2075 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2076 ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2078 desc.desc2.dwSize = 0;
2079 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2080 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size 0 returned %08x\n", hr);
2081 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2082 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2083 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size 0 returned %08x\n", hr);
2084 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2086 desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2087 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2088 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2089 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2090 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2091 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2092 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2094 desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2095 hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2096 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2097 if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2098 hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2099 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2100 if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2102 IDirectDrawSurface7_Release(surface7);
2103 IDirectDrawSurface_Release(surface1);
2106 static void SurfaceCapsTest(void)
2108 DDSURFACEDESC create;
2109 DDSURFACEDESC desc;
2110 HRESULT hr;
2111 IDirectDrawSurface *surface1 = NULL;
2112 DDSURFACEDESC2 create2, desc2;
2113 IDirectDrawSurface7 *surface7 = NULL;
2114 IDirectDraw7 *dd7 = NULL;
2115 DWORD create_caps[] = {
2116 DDSCAPS_OFFSCREENPLAIN,
2117 DDSCAPS_TEXTURE,
2118 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD,
2120 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2121 DDSCAPS_PRIMARYSURFACE,
2122 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY,
2123 DDSCAPS_3DDEVICE,
2124 DDSCAPS_ZBUFFER,
2125 DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN
2127 DWORD expected_caps[] = {
2128 DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2129 DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2130 DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD,
2131 DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2132 DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2133 DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_VISIBLE,
2134 DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_VISIBLE,
2135 DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2136 DDSCAPS_ZBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY,
2137 DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM
2139 UINT i;
2141 /* Tests various surface flags, what changes do they undergo during
2142 * surface creation. Forsaken engine expects texture surfaces without
2143 * memory flag to get a video memory flag right after creation. */
2145 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
2147 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
2148 return ;
2151 for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2153 memset(&create, 0, sizeof(create));
2154 create.dwSize = sizeof(create);
2155 create.ddsCaps.dwCaps = create_caps[i];
2156 create.dwFlags = DDSD_CAPS;
2158 if (!(create.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2160 create.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2161 create.dwHeight = 128;
2162 create.dwWidth = 128;
2165 if (create.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
2167 create.dwFlags |= DDSD_PIXELFORMAT;
2168 create.ddpfPixelFormat.dwSize = sizeof(create.ddpfPixelFormat);
2169 create.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2170 U1(create.ddpfPixelFormat).dwZBufferBitDepth = 16;
2171 U3(create.ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
2174 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2175 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2177 if (SUCCEEDED(hr))
2179 memset(&desc, 0, sizeof(desc));
2180 desc.dwSize = sizeof(DDSURFACEDESC);
2181 hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc);
2182 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2184 ok(desc.ddsCaps.dwCaps == expected_caps[i],
2185 "GetSurfaceDesc test %d returned caps %x, expected %x\n",
2186 i, desc.ddsCaps.dwCaps, expected_caps[i]);
2188 IDirectDrawSurface_Release(surface1);
2192 /* Test for differences in ddraw 7 */
2193 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2194 ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
2195 if (FAILED(hr))
2197 skip("Failed to get IDirectDraw7 interface, skipping tests\n");
2199 else
2201 for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2203 memset(&create2, 0, sizeof(create2));
2204 create2.dwSize = sizeof(create2);
2205 create2.ddsCaps.dwCaps = create_caps[i];
2206 create2.dwFlags = DDSD_CAPS;
2208 if (!(create2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2210 create2.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2211 create2.dwHeight = 128;
2212 create2.dwWidth = 128;
2215 if (create2.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
2217 create2.dwFlags |= DDSD_PIXELFORMAT;
2218 U4(create2).ddpfPixelFormat.dwSize = sizeof(U4(create2).ddpfPixelFormat);
2219 U4(create2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2220 U1(U4(create2).ddpfPixelFormat).dwZBufferBitDepth = 16;
2221 U3(U4(create2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
2224 hr = IDirectDraw7_CreateSurface(dd7, &create2, &surface7, NULL);
2225 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2227 if (SUCCEEDED(hr))
2229 memset(&desc2, 0, sizeof(desc2));
2230 desc2.dwSize = sizeof(DDSURFACEDESC2);
2231 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc2);
2232 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2234 ok(desc2.ddsCaps.dwCaps == expected_caps[i],
2235 "GetSurfaceDesc test %d returned caps %x, expected %x\n",
2236 i, desc2.ddsCaps.dwCaps, expected_caps[i]);
2238 IDirectDrawSurface7_Release(surface7);
2242 IDirectDraw7_Release(dd7);
2245 memset(&create, 0, sizeof(create));
2246 create.dwSize = sizeof(create);
2247 create.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2248 create.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY;
2249 create.dwWidth = 64;
2250 create.dwHeight = 64;
2251 hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2252 ok(hr == DDERR_INVALIDCAPS, "Creating a SYSMEM | VIDMEM surface returned 0x%08x, expected DDERR_INVALIDCAPS\n", hr);
2253 if(surface1) IDirectDrawSurface_Release(surface1);
2256 static BOOL can_create_primary_surface(void)
2258 DDSURFACEDESC ddsd;
2259 IDirectDrawSurface *surface;
2260 HRESULT hr;
2262 memset(&ddsd, 0, sizeof(ddsd));
2263 ddsd.dwSize = sizeof(ddsd);
2264 ddsd.dwFlags = DDSD_CAPS;
2265 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2266 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2267 if(FAILED(hr)) return FALSE;
2268 IDirectDrawSurface_Release(surface);
2269 return TRUE;
2272 static void GetDCTest(void)
2274 DDSURFACEDESC ddsd;
2275 DDSURFACEDESC2 ddsd2;
2276 IDirectDrawSurface *surf;
2277 IDirectDrawSurface4 *surf4;
2278 IDirectDrawSurface7 *surf7;
2279 IDirectDrawSurface *tmp;
2280 IDirectDrawSurface7 *tmp7;
2281 HRESULT hr;
2282 IDirectDraw4 *dd4;
2283 IDirectDraw7 *dd7;
2284 HDC dc;
2285 ULONG ref;
2287 memset(&ddsd, 0, sizeof(ddsd));
2288 ddsd.dwSize = sizeof(ddsd);
2289 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2290 ddsd.dwWidth = 64;
2291 ddsd.dwHeight = 64;
2292 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2293 memset(&ddsd2, 0, sizeof(ddsd2));
2294 ddsd2.dwSize = sizeof(ddsd2);
2295 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2296 ddsd2.dwWidth = 64;
2297 ddsd2.dwHeight = 64;
2298 ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2300 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
2301 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2303 surf = NULL;
2304 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
2305 ok(hr == DD_OK, "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
2307 hr = IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)&surf);
2308 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
2310 ref = getRefcount((IUnknown *) surf);
2311 ok(ref == 1, "Refcount is %u, expected 1\n", ref);
2312 ref = getRefcount((IUnknown *) surf4);
2313 ok(ref == 1, "Refcount is %u, expected 1\n", ref);
2315 hr = IDirectDrawSurface4_GetDC(surf4, &dc);
2316 ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
2318 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, NULL);
2319 ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
2321 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
2322 ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
2323 ok(tmp == surf, "Expected surface %p, got %p.\n\n", surf, tmp);
2325 ref = getRefcount((IUnknown *) surf);
2326 ok(ref == 2, "Refcount is %u, expected 2\n", ref);
2327 ref = getRefcount((IUnknown *) tmp);
2328 ok(ref == 2, "Refcount is %u, expected 2\n", ref);
2329 ref = getRefcount((IUnknown *) surf4);
2330 ok(ref == 1, "Refcount is %u, expected 1\n", ref);
2332 hr = IDirectDrawSurface4_ReleaseDC(surf4, dc);
2333 ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
2335 IDirectDrawSurface_Release(tmp);
2337 dc = CreateCompatibleDC(NULL);
2338 ok(!!dc, "CreateCompatibleDC failed.\n");
2340 tmp = (IDirectDrawSurface *)0xdeadbeef;
2341 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
2342 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
2343 ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
2345 ok(DeleteDC(dc), "DeleteDC failed.\n");
2347 tmp = (IDirectDrawSurface *)0xdeadbeef;
2348 hr = IDirectDraw4_GetSurfaceFromDC(dd4, NULL, (IDirectDrawSurface4 **)&tmp);
2349 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
2350 ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
2352 IDirectDrawSurface4_Release(surf4);
2353 IDirectDrawSurface_Release(surf);
2354 IDirectDraw4_Release(dd4);
2356 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2357 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2359 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
2360 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
2362 hr = IDirectDrawSurface7_GetDC(surf7, &dc);
2363 ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
2365 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, NULL);
2366 ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
2368 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
2369 ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
2370 ok(tmp7 == surf7, "Expected surface %p, got %p.\n\n", surf7, tmp7);
2371 IDirectDrawSurface7_Release(tmp7);
2373 hr = IDirectDrawSurface7_ReleaseDC(surf7, dc);
2374 ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
2376 dc = CreateCompatibleDC(NULL);
2377 ok(!!dc, "CreateCompatibleDC failed.\n");
2379 tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
2380 hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
2381 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
2382 ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
2384 ok(DeleteDC(dc), "DeleteDC failed.\n");
2386 tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
2387 hr = IDirectDraw7_GetSurfaceFromDC(dd7, NULL, (IDirectDrawSurface7 **)&tmp7);
2388 ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
2389 ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
2391 IDirectDrawSurface7_Release(surf7);
2392 IDirectDraw7_Release(dd7);
2395 static void BackBufferCreateSurfaceTest(void)
2397 DDSURFACEDESC ddsd;
2398 DDSURFACEDESC created_ddsd;
2399 DDSURFACEDESC2 ddsd2;
2400 IDirectDrawSurface *surf;
2401 IDirectDrawSurface4 *surf4;
2402 IDirectDrawSurface7 *surf7;
2403 HRESULT hr;
2404 IDirectDraw2 *dd2;
2405 IDirectDraw4 *dd4;
2406 IDirectDraw7 *dd7;
2408 const DWORD caps = DDSCAPS_BACKBUFFER;
2409 const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
2411 if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
2413 skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
2414 return ;
2417 memset(&ddsd, 0, sizeof(ddsd));
2418 ddsd.dwSize = sizeof(ddsd);
2419 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2420 ddsd.dwWidth = 64;
2421 ddsd.dwHeight = 64;
2422 ddsd.ddsCaps.dwCaps = caps;
2423 memset(&ddsd2, 0, sizeof(ddsd2));
2424 ddsd2.dwSize = sizeof(ddsd2);
2425 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2426 ddsd2.dwWidth = 64;
2427 ddsd2.dwHeight = 64;
2428 ddsd2.ddsCaps.dwCaps = caps;
2429 memset(&created_ddsd, 0, sizeof(created_ddsd));
2430 created_ddsd.dwSize = sizeof(DDSURFACEDESC);
2432 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
2433 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
2434 if (surf != NULL)
2436 hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
2437 ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
2438 ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
2439 "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
2440 expected_caps);
2441 IDirectDrawSurface_Release(surf);
2444 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
2445 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2447 hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
2448 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
2449 DDERR_INVALIDCAPS, hr);
2451 IDirectDraw2_Release(dd2);
2453 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
2454 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2456 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
2457 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
2458 DDERR_INVALIDCAPS, hr);
2460 IDirectDraw4_Release(dd4);
2462 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2463 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2465 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
2466 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
2467 DDERR_INVALIDCAPS, hr);
2469 IDirectDraw7_Release(dd7);
2472 static void BackBufferAttachmentFlipTest(void)
2474 HRESULT hr;
2475 IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
2476 DDSURFACEDESC ddsd;
2477 HWND window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
2478 100, 100, 160, 160, NULL, NULL, NULL, NULL);
2480 hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2481 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
2483 /* Perform attachment tests on a back-buffer */
2484 memset(&ddsd, 0, sizeof(ddsd));
2485 ddsd.dwSize = sizeof(ddsd);
2486 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2487 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
2488 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
2489 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
2490 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
2491 ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
2493 if (surface2 != NULL)
2495 /* Try a single primary and a two back buffers */
2496 memset(&ddsd, 0, sizeof(ddsd));
2497 ddsd.dwSize = sizeof(ddsd);
2498 ddsd.dwFlags = DDSD_CAPS;
2499 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2500 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
2501 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2503 memset(&ddsd, 0, sizeof(ddsd));
2504 ddsd.dwSize = sizeof(ddsd);
2505 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2506 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
2507 ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
2508 ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
2509 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
2510 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2512 /* This one has a different size */
2513 memset(&ddsd, 0, sizeof(ddsd));
2514 ddsd.dwSize = sizeof(ddsd);
2515 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2516 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
2517 ddsd.dwWidth = 128;
2518 ddsd.dwHeight = 128;
2519 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
2520 ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2522 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
2523 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
2524 "Attaching a back buffer to a front buffer returned %08x\n", hr);
2525 if(SUCCEEDED(hr))
2527 /* Try flipping the surfaces */
2528 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
2529 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2530 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
2531 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2533 /* Try the reverse without detaching first */
2534 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
2535 ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
2536 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
2537 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
2539 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
2540 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
2541 "Attaching a front buffer to a back buffer returned %08x\n", hr);
2542 if(SUCCEEDED(hr))
2544 /* Try flipping the surfaces */
2545 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
2546 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2547 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
2548 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2550 /* Try to detach reversed */
2551 hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
2552 ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
2553 /* Now the proper detach */
2554 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
2555 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
2557 hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
2558 todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
2559 "Attaching a back buffer to another back buffer returned %08x\n", hr);
2560 if(SUCCEEDED(hr))
2562 /* Try flipping the surfaces */
2563 hr = IDirectDrawSurface_Flip(surface3, NULL, DDFLIP_WAIT);
2564 todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2565 hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
2566 todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2567 hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
2568 ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
2570 hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
2571 ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
2573 hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
2574 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
2575 hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
2576 ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
2578 IDirectDrawSurface_Release(surface4);
2579 IDirectDrawSurface_Release(surface3);
2580 IDirectDrawSurface_Release(surface2);
2581 IDirectDrawSurface_Release(surface1);
2584 hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
2585 ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
2587 DestroyWindow(window);
2590 static void CreateSurfaceBadCapsSizeTest(void)
2592 DDSURFACEDESC ddsd_ok;
2593 DDSURFACEDESC ddsd_bad1;
2594 DDSURFACEDESC ddsd_bad2;
2595 DDSURFACEDESC ddsd_bad3;
2596 DDSURFACEDESC ddsd_bad4;
2597 DDSURFACEDESC2 ddsd2_ok;
2598 DDSURFACEDESC2 ddsd2_bad1;
2599 DDSURFACEDESC2 ddsd2_bad2;
2600 DDSURFACEDESC2 ddsd2_bad3;
2601 DDSURFACEDESC2 ddsd2_bad4;
2602 IDirectDrawSurface *surf;
2603 IDirectDrawSurface4 *surf4;
2604 IDirectDrawSurface7 *surf7;
2605 HRESULT hr;
2606 IDirectDraw2 *dd2;
2607 IDirectDraw4 *dd4;
2608 IDirectDraw7 *dd7;
2610 const DWORD caps = DDSCAPS_OFFSCREENPLAIN;
2612 memset(&ddsd_ok, 0, sizeof(ddsd_ok));
2613 ddsd_ok.dwSize = sizeof(ddsd_ok);
2614 ddsd_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2615 ddsd_ok.dwWidth = 64;
2616 ddsd_ok.dwHeight = 64;
2617 ddsd_ok.ddsCaps.dwCaps = caps;
2618 ddsd_bad1 = ddsd_ok;
2619 ddsd_bad1.dwSize--;
2620 ddsd_bad2 = ddsd_ok;
2621 ddsd_bad2.dwSize++;
2622 ddsd_bad3 = ddsd_ok;
2623 ddsd_bad3.dwSize = 0;
2624 ddsd_bad4 = ddsd_ok;
2625 ddsd_bad4.dwSize = sizeof(DDSURFACEDESC2);
2627 memset(&ddsd2_ok, 0, sizeof(ddsd2_ok));
2628 ddsd2_ok.dwSize = sizeof(ddsd2_ok);
2629 ddsd2_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2630 ddsd2_ok.dwWidth = 64;
2631 ddsd2_ok.dwHeight = 64;
2632 ddsd2_ok.ddsCaps.dwCaps = caps;
2633 ddsd2_bad1 = ddsd2_ok;
2634 ddsd2_bad1.dwSize--;
2635 ddsd2_bad2 = ddsd2_ok;
2636 ddsd2_bad2.dwSize++;
2637 ddsd2_bad3 = ddsd2_ok;
2638 ddsd2_bad3.dwSize = 0;
2639 ddsd2_bad4 = ddsd2_ok;
2640 ddsd2_bad4.dwSize = sizeof(DDSURFACEDESC);
2642 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_ok, &surf, NULL);
2643 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
2644 IDirectDrawSurface_Release(surf);
2646 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad1, &surf, NULL);
2647 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2648 DDERR_INVALIDPARAMS, hr);
2649 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad2, &surf, NULL);
2650 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2651 DDERR_INVALIDPARAMS, hr);
2652 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad3, &surf, NULL);
2653 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2654 DDERR_INVALIDPARAMS, hr);
2655 hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad4, &surf, NULL);
2656 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2657 DDERR_INVALIDPARAMS, hr);
2658 hr = IDirectDraw_CreateSurface(lpDD, NULL, &surf, NULL);
2659 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2660 DDERR_INVALIDPARAMS, hr);
2662 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
2663 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2665 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_ok, &surf, NULL);
2666 ok(SUCCEEDED(hr), "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
2667 IDirectDrawSurface_Release(surf);
2669 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad1, &surf, NULL);
2670 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2671 DDERR_INVALIDPARAMS, hr);
2672 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad2, &surf, NULL);
2673 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2674 DDERR_INVALIDPARAMS, hr);
2675 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad3, &surf, NULL);
2676 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2677 DDERR_INVALIDPARAMS, hr);
2678 hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad4, &surf, NULL);
2679 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2680 DDERR_INVALIDPARAMS, hr);
2681 hr = IDirectDraw2_CreateSurface(dd2, NULL, &surf, NULL);
2682 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2683 DDERR_INVALIDPARAMS, hr);
2685 IDirectDraw2_Release(dd2);
2687 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
2688 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2690 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_ok, &surf4, NULL);
2691 ok(SUCCEEDED(hr), "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
2692 IDirectDrawSurface4_Release(surf4);
2694 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad1, &surf4, NULL);
2695 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2696 DDERR_INVALIDPARAMS, hr);
2697 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad2, &surf4, NULL);
2698 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2699 DDERR_INVALIDPARAMS, hr);
2700 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad3, &surf4, NULL);
2701 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2702 DDERR_INVALIDPARAMS, hr);
2703 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad4, &surf4, NULL);
2704 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2705 DDERR_INVALIDPARAMS, hr);
2706 hr = IDirectDraw4_CreateSurface(dd4, NULL, &surf4, NULL);
2707 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2708 DDERR_INVALIDPARAMS, hr);
2710 IDirectDraw4_Release(dd4);
2712 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2713 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
2715 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_ok, &surf7, NULL);
2716 ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
2717 IDirectDrawSurface7_Release(surf7);
2719 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad1, &surf7, NULL);
2720 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2721 DDERR_INVALIDPARAMS, hr);
2722 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad2, &surf7, NULL);
2723 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2724 DDERR_INVALIDPARAMS, hr);
2725 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad3, &surf7, NULL);
2726 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2727 DDERR_INVALIDPARAMS, hr);
2728 hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad4, &surf7, NULL);
2729 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2730 DDERR_INVALIDPARAMS, hr);
2731 hr = IDirectDraw7_CreateSurface(dd7, NULL, &surf7, NULL);
2732 ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
2733 DDERR_INVALIDPARAMS, hr);
2735 IDirectDraw7_Release(dd7);
2738 static void reset_ddsd(DDSURFACEDESC *ddsd)
2740 memset(ddsd, 0, sizeof(*ddsd));
2741 ddsd->dwSize = sizeof(*ddsd);
2744 static void no_ddsd_caps_test(void)
2746 DDSURFACEDESC ddsd;
2747 HRESULT hr;
2748 IDirectDrawSurface *surface;
2750 reset_ddsd(&ddsd);
2751 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
2752 ddsd.dwWidth = 128;
2753 ddsd.dwHeight = 128;
2754 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2755 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2756 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
2757 reset_ddsd(&ddsd);
2758 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
2759 IDirectDrawSurface_Release(surface);
2760 ok(ddsd.dwFlags & DDSD_CAPS, "DDSD_CAPS is not set\n");
2761 ok(ddsd.ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN, "DDSCAPS_OFFSCREENPLAIN is not set\n");
2763 reset_ddsd(&ddsd);
2764 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2765 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2766 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
2767 reset_ddsd(&ddsd);
2768 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
2769 IDirectDrawSurface_Release(surface);
2770 ok(ddsd.dwFlags & DDSD_CAPS, "DDSD_CAPS is not set\n");
2771 ok(ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE, "DDSCAPS_OFFSCREENPLAIN is not set\n");
2773 reset_ddsd(&ddsd);
2774 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
2775 ddsd.dwWidth = 128;
2776 ddsd.dwHeight = 128;
2777 ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
2778 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2779 ok(hr == DDERR_INVALIDCAPS, "IDirectDraw_CreateSurface returned %#x, expected DDERR_INVALIDCAPS.\n", hr);
2782 static void dump_format(const DDPIXELFORMAT *fmt)
2784 trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %u\n", fmt->dwFlags, fmt->dwFourCC,
2785 U1(*fmt).dwZBufferBitDepth, U2(*fmt).dwStencilBitDepth);
2786 trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", U3(*fmt).dwZBitMask,
2787 U4(*fmt).dwStencilBitMask, U5(*fmt).dwRGBZBitMask);
2790 static void zbufferbitdepth_test(void)
2792 enum zfmt_succeed
2794 ZFMT_SUPPORTED_ALWAYS,
2795 ZFMT_SUPPORTED_NEVER,
2796 ZFMT_SUPPORTED_HWDEPENDENT
2798 struct
2800 DWORD depth;
2801 enum zfmt_succeed supported;
2802 DDPIXELFORMAT pf;
2804 test_data[] =
2807 16, ZFMT_SUPPORTED_ALWAYS,
2809 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
2810 {16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
2814 24, ZFMT_SUPPORTED_HWDEPENDENT,
2816 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
2817 {24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
2821 32, ZFMT_SUPPORTED_HWDEPENDENT,
2823 sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
2824 {32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
2827 /* Returns DDERR_INVALIDPARAMS instead of DDERR_INVALIDPIXELFORMAT.
2828 * Disabled for now
2830 0, ZFMT_SUPPORTED_NEVER
2834 15, ZFMT_SUPPORTED_NEVER
2837 28, ZFMT_SUPPORTED_NEVER
2840 40, ZFMT_SUPPORTED_NEVER
2844 DDSURFACEDESC ddsd;
2845 IDirectDrawSurface *surface;
2846 HRESULT hr;
2847 unsigned int i;
2848 DDCAPS caps;
2850 memset(&caps, 0, sizeof(caps));
2851 caps.dwSize = sizeof(caps);
2852 hr = IDirectDraw_GetCaps(lpDD, &caps, NULL);
2853 ok(SUCCEEDED(hr), "IDirectDraw_GetCaps failed, hr %#x.\n", hr);
2854 if (!(caps.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
2856 skip("Z buffers not supported, skipping DDSD_ZBUFFERBITDEPTH test\n");
2857 return;
2860 for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
2862 reset_ddsd(&ddsd);
2863 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH;
2864 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
2865 ddsd.dwWidth = 256;
2866 ddsd.dwHeight = 256;
2867 U2(ddsd).dwZBufferBitDepth = test_data[i].depth;
2869 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2870 if (test_data[i].supported == ZFMT_SUPPORTED_ALWAYS)
2872 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
2874 else if (test_data[i].supported == ZFMT_SUPPORTED_NEVER)
2876 ok(hr == DDERR_INVALIDPIXELFORMAT, "IDirectDraw_CreateSurface returned %#x, expected %x.\n",
2877 hr, DDERR_INVALIDPIXELFORMAT);
2879 if (!surface) continue;
2881 reset_ddsd(&ddsd);
2882 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
2883 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
2884 IDirectDrawSurface_Release(surface);
2886 ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
2887 ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
2888 /* Yet the ddpfPixelFormat member contains valid data */
2889 if (memcmp(&ddsd.ddpfPixelFormat, &test_data[i].pf, ddsd.ddpfPixelFormat.dwSize))
2891 ok(0, "Unexpected format for depth %u\n", test_data[i].depth);
2892 dump_format(&ddsd.ddpfPixelFormat);
2896 /* DDSD_ZBUFFERBITDEPTH vs DDSD_PIXELFORMAT? */
2897 reset_ddsd(&ddsd);
2898 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_ZBUFFERBITDEPTH;
2899 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
2900 ddsd.dwWidth = 256;
2901 ddsd.dwHeight = 256;
2902 U2(ddsd).dwZBufferBitDepth = 24;
2903 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2904 ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2905 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth = 16;
2906 U3(ddsd.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
2908 surface = NULL;
2909 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2910 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
2911 if (!surface) return;
2912 reset_ddsd(&ddsd);
2913 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
2914 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
2915 IDirectDrawSurface_Release(surface);
2916 ok(U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth == 16, "Expected a 16bpp depth buffer, got %ubpp\n",
2917 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth);
2918 ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
2919 ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
2920 ok(U2(ddsd).dwZBufferBitDepth == 16, "Expected dwZBufferBitDepth=16, got %u\n",
2921 U2(ddsd).dwZBufferBitDepth);
2923 /* DDSD_PIXELFORMAT vs invalid ZBUFFERBITDEPTH */
2924 reset_ddsd(&ddsd);
2925 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_PIXELFORMAT;
2926 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
2927 ddsd.dwWidth = 256;
2928 ddsd.dwHeight = 256;
2929 U2(ddsd).dwZBufferBitDepth = 40;
2930 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2931 ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2932 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth = 16;
2933 U3(ddsd.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
2934 surface = NULL;
2935 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2936 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
2937 if (surface) IDirectDrawSurface_Release(surface);
2939 /* Create a PIXELFORMAT-only surface, see if ZBUFFERBITDEPTH is set */
2940 reset_ddsd(&ddsd);
2941 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
2942 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
2943 ddsd.dwWidth = 256;
2944 ddsd.dwHeight = 256;
2945 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2946 ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2947 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth = 16;
2948 U3(ddsd.ddpfPixelFormat).dwZBitMask = 0x0000ffff;
2949 surface = NULL;
2950 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2951 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
2952 reset_ddsd(&ddsd);
2953 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
2954 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
2955 IDirectDrawSurface_Release(surface);
2956 ok(U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth == 16, "Expected a 16bpp depth buffer, got %ubpp\n",
2957 U1(ddsd.ddpfPixelFormat).dwZBufferBitDepth);
2958 ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
2959 ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
2960 ok(U2(ddsd).dwZBufferBitDepth == 16, "Expected dwZBufferBitDepth=16, got %u\n",
2961 U2(ddsd).dwZBufferBitDepth);
2964 static void test_ddsd(DDSURFACEDESC *ddsd, BOOL expect_pf, BOOL expect_zd, const char *name, DWORD z_bit_depth)
2966 IDirectDrawSurface *surface;
2967 IDirectDrawSurface7 *surface7;
2968 HRESULT hr;
2969 DDSURFACEDESC out;
2970 DDSURFACEDESC2 out2;
2972 hr = IDirectDraw_CreateSurface(lpDD, ddsd, &surface, NULL);
2973 if (hr == DDERR_NOZBUFFERHW)
2975 skip("Z buffers not supported, skipping Z flag test\n");
2976 return;
2978 ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
2979 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **) &surface7);
2980 ok(SUCCEEDED(hr), "IDirectDrawSurface_QueryInterface failed, hr %#x.\n", hr);
2982 reset_ddsd(&out);
2983 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &out);
2984 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
2985 memset(&out2, 0, sizeof(out2));
2986 out2.dwSize = sizeof(out2);
2987 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &out2);
2988 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
2990 if (expect_pf)
2992 ok(out.dwFlags & DDSD_PIXELFORMAT, "%s surface: Expected DDSD_PIXELFORMAT to be set\n", name);
2993 ok(out2.dwFlags & DDSD_PIXELFORMAT,
2994 "%s surface: Expected DDSD_PIXELFORMAT to be set in DDSURFACEDESC2\n", name);
2996 else
2998 ok(!(out.dwFlags & DDSD_PIXELFORMAT), "%s surface: Expected DDSD_PIXELFORMAT not to be set\n", name);
2999 ok(out2.dwFlags & DDSD_PIXELFORMAT,
3000 "%s surface: Expected DDSD_PIXELFORMAT to be set in DDSURFACEDESC2\n", name);
3002 if (expect_zd)
3004 ok(out.dwFlags & DDSD_ZBUFFERBITDEPTH, "%s surface: Expected DDSD_ZBUFFERBITDEPTH to be set\n", name);
3005 ok(U2(out).dwZBufferBitDepth == z_bit_depth, "ZBufferBitDepth is %u, expected %u\n",
3006 U2(out).dwZBufferBitDepth, z_bit_depth);
3007 ok(!(out2.dwFlags & DDSD_ZBUFFERBITDEPTH),
3008 "%s surface: Did not expect DDSD_ZBUFFERBITDEPTH to be set in DDSURFACEDESC2\n", name);
3009 /* dwMipMapCount and dwZBufferBitDepth share the same union */
3010 ok(U2(out2).dwMipMapCount == 0, "dwMipMapCount is %u, expected 0\n", U2(out2).dwMipMapCount);
3012 else
3014 ok(!(out.dwFlags & DDSD_ZBUFFERBITDEPTH), "%s surface: Expected DDSD_ZBUFFERBITDEPTH not to be set\n", name);
3015 ok(U2(out).dwZBufferBitDepth == 0, "ZBufferBitDepth is %u, expected 0\n", U2(out).dwZBufferBitDepth);
3016 ok(!(out2.dwFlags & DDSD_ZBUFFERBITDEPTH),
3017 "%s surface: Did not expect DDSD_ZBUFFERBITDEPTH to be set in DDSURFACEDESC2\n", name);
3018 ok(U2(out2).dwMipMapCount == 0, "dwMipMapCount is %u, expected 0\n", U2(out2).dwMipMapCount);
3021 reset_ddsd(&out);
3022 hr = IDirectDrawSurface_Lock(surface, NULL, &out, 0, NULL);
3023 if (SUCCEEDED(hr))
3025 hr = IDirectDrawSurface_Unlock(surface, NULL);
3026 ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
3028 /* DDSD_ZBUFFERBITDEPTH is never set on Nvidia, but follows GetSurfaceDesc rules on AMD */
3029 if (!expect_zd)
3031 ok(!(out.dwFlags & DDSD_ZBUFFERBITDEPTH),
3032 "Lock %s surface: Expected DDSD_ZBUFFERBITDEPTH not to be set\n", name);
3035 /* DDSD_PIXELFORMAT follows GetSurfaceDesc rules */
3036 if (expect_pf)
3038 ok(out.dwFlags & DDSD_PIXELFORMAT, "%s surface: Expected DDSD_PIXELFORMAT to be set\n", name);
3040 else
3042 ok(!(out.dwFlags & DDSD_PIXELFORMAT),
3043 "Lock %s surface: Expected DDSD_PIXELFORMAT not to be set\n", name);
3045 if (out.dwFlags & DDSD_ZBUFFERBITDEPTH)
3046 ok(U2(out).dwZBufferBitDepth == z_bit_depth, "ZBufferBitDepth is %u, expected %u\n",
3047 U2(out).dwZBufferBitDepth, z_bit_depth);
3048 else
3049 ok(U2(out).dwZBufferBitDepth == 0, "ZBufferBitDepth is %u, expected 0\n", U2(out).dwZBufferBitDepth);
3052 hr = IDirectDrawSurface7_Lock(surface7, NULL, &out2, 0, NULL);
3053 ok(SUCCEEDED(hr), "IDirectDrawSurface7_Lock failed, hr %#x.\n", hr);
3054 if (SUCCEEDED(hr))
3056 hr = IDirectDrawSurface7_Unlock(surface7, NULL);
3057 ok(SUCCEEDED(hr), "IDirectDrawSurface7_Unlock failed, hr %#x.\n", hr);
3058 /* DDSD_PIXELFORMAT is always set, DDSD_ZBUFFERBITDEPTH never */
3059 ok(out2.dwFlags & DDSD_PIXELFORMAT,
3060 "Lock %s surface: Expected DDSD_PIXELFORMAT to be set in DDSURFACEDESC2\n", name);
3061 ok(!(out2.dwFlags & DDSD_ZBUFFERBITDEPTH),
3062 "Lock %s surface: Did not expect DDSD_ZBUFFERBITDEPTH to be set in DDSURFACEDESC2\n", name);
3063 ok(U2(out2).dwMipMapCount == 0, "dwMipMapCount is %u, expected 0\n", U2(out2).dwMipMapCount);
3066 IDirectDrawSurface7_Release(surface7);
3067 IDirectDrawSurface_Release(surface);
3070 static void pixelformat_flag_test(void)
3072 DDSURFACEDESC ddsd;
3073 DDCAPS caps;
3074 HRESULT hr;
3076 memset(&caps, 0, sizeof(caps));
3077 caps.dwSize = sizeof(caps);
3078 hr = IDirectDraw_GetCaps(lpDD, &caps, NULL);
3079 ok(SUCCEEDED(hr), "IDirectDraw_GetCaps failed, hr %#x.\n", hr);
3080 if (!(caps.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
3082 skip("Z buffers not supported, skipping DDSD_PIXELFORMAT test\n");
3083 return;
3086 reset_ddsd(&ddsd);
3087 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3088 ddsd.dwWidth = 64;
3089 ddsd.dwHeight = 64;
3090 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3091 test_ddsd(&ddsd, TRUE, FALSE, "offscreen plain", ~0U);
3093 reset_ddsd(&ddsd);
3094 ddsd.dwFlags = DDSD_CAPS;
3095 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3096 test_ddsd(&ddsd, TRUE, FALSE, "primary", ~0U);
3098 reset_ddsd(&ddsd);
3099 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_ZBUFFERBITDEPTH;
3100 ddsd.dwWidth = 64;
3101 ddsd.dwHeight = 64;
3102 U2(ddsd).dwZBufferBitDepth = 16;
3103 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
3104 test_ddsd(&ddsd, FALSE, TRUE, "Z buffer", 16);
3107 static BOOL fourcc_supported(DWORD fourcc, DWORD caps)
3109 DDSURFACEDESC ddsd;
3110 HRESULT hr;
3111 IDirectDrawSurface *surface;
3113 reset_ddsd(&ddsd);
3114 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
3115 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
3116 ddsd.dwWidth = 4;
3117 ddsd.dwHeight = 4;
3118 ddsd.ddsCaps.dwCaps = caps;
3119 ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
3120 ddsd.ddpfPixelFormat.dwFourCC = fourcc;
3121 hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3122 if (FAILED(hr))
3124 return FALSE;
3126 IDirectDrawSurface_Release(surface);
3127 return TRUE;
3130 static void partial_block_lock_test(void)
3132 IDirectDrawSurface7 *surface;
3133 HRESULT hr;
3134 DDSURFACEDESC2 ddsd;
3135 IDirectDraw7 *dd7;
3136 const struct
3138 DWORD caps, caps2;
3139 const char *name;
3140 BOOL success;
3142 pools[] =
3145 DDSCAPS_VIDEOMEMORY, 0,
3146 "D3DPOOL_DEFAULT", FALSE
3149 DDSCAPS_SYSTEMMEMORY, 0,
3150 "D3DPOOL_SYSTEMMEM", TRUE
3153 0, DDSCAPS2_TEXTUREMANAGE,
3154 "D3DPOOL_MANAGED", TRUE
3157 const struct
3159 DWORD fourcc;
3160 DWORD caps;
3161 const char *name;
3162 unsigned int block_width;
3163 unsigned int block_height;
3165 formats[] =
3167 {MAKEFOURCC('D','X','T','1'), DDSCAPS_TEXTURE, "D3DFMT_DXT1", 4, 4},
3168 {MAKEFOURCC('D','X','T','2'), DDSCAPS_TEXTURE, "D3DFMT_DXT2", 4, 4},
3169 {MAKEFOURCC('D','X','T','3'), DDSCAPS_TEXTURE, "D3DFMT_DXT3", 4, 4},
3170 {MAKEFOURCC('D','X','T','4'), DDSCAPS_TEXTURE, "D3DFMT_DXT4", 4, 4},
3171 {MAKEFOURCC('D','X','T','5'), DDSCAPS_TEXTURE, "D3DFMT_DXT5", 4, 4},
3172 /* ATI2N surfaces aren't available in ddraw */
3173 {MAKEFOURCC('U','Y','V','Y'), DDSCAPS_OVERLAY, "D3DFMT_UYVY", 2, 1},
3174 {MAKEFOURCC('Y','U','Y','2'), DDSCAPS_OVERLAY, "D3DFMT_YUY2", 2, 1},
3176 unsigned int i, j;
3177 RECT rect;
3179 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3180 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3182 for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
3184 if (!fourcc_supported(formats[i].fourcc, formats[i].caps | DDSCAPS_VIDEOMEMORY))
3186 skip("%s surfaces not supported, skipping partial block lock test\n", formats[i].name);
3187 continue;
3190 for (j = 0; j < (sizeof(pools) / sizeof(*pools)); j++)
3192 if (formats[i].caps & DDSCAPS_OVERLAY && !(pools[j].caps & DDSCAPS_VIDEOMEMORY))
3193 continue;
3195 memset(&ddsd, 0, sizeof(ddsd));
3196 ddsd.dwSize = sizeof(ddsd);
3197 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
3198 ddsd.dwWidth = 128;
3199 ddsd.dwHeight = 128;
3200 ddsd.ddsCaps.dwCaps = pools[j].caps | formats[i].caps;
3201 ddsd.ddsCaps.dwCaps2 = pools[j].caps2;
3202 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
3203 U4(ddsd).ddpfPixelFormat.dwFourCC = formats[i].fourcc;
3204 hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3205 ok(SUCCEEDED(hr), "CreateSurface failed, hr %#x, format %s, pool %s\n",
3206 hr, formats[i].name, pools[j].name);
3208 /* All Windows versions allow partial block locks with DDSCAPS_SYSTEMMEMORY and
3209 * DDSCAPS2_TEXTUREMANAGE, just like in d3d8 and d3d9. Windows XP also allows those locks
3210 * with DDSCAPS_VIDEOMEMORY. Windows Vista and Windows 7 disallow partial locks of vidmem
3211 * surfaces, making the ddraw behavior consistent with d3d8 and 9.
3213 * Mark the Windows XP behavior as broken until we find an application that needs it */
3214 if (formats[i].block_width > 1)
3216 SetRect(&rect, formats[i].block_width >> 1, 0, formats[i].block_width, formats[i].block_height);
3217 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3218 ok(SUCCEEDED(hr) == pools[j].success || broken(SUCCEEDED(hr)),
3219 "Partial block lock %s, expected %s, format %s, pool %s\n",
3220 SUCCEEDED(hr) ? "succeeded" : "failed", pools[j].success ? "success" : "failure",
3221 formats[i].name, pools[j].name);
3222 if (SUCCEEDED(hr))
3224 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3225 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3228 SetRect(&rect, 0, 0, formats[i].block_width >> 1, formats[i].block_height);
3229 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3230 ok(SUCCEEDED(hr) == pools[j].success || broken(SUCCEEDED(hr)),
3231 "Partial block lock %s, expected %s, format %s, pool %s\n",
3232 SUCCEEDED(hr) ? "succeeded" : "failed", pools[j].success ? "success" : "failure",
3233 formats[i].name, pools[j].name);
3234 if (SUCCEEDED(hr))
3236 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3237 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3241 if (formats[i].block_height > 1)
3243 SetRect(&rect, 0, formats[i].block_height >> 1, formats[i].block_width, formats[i].block_height);
3244 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3245 ok(SUCCEEDED(hr) == pools[j].success || broken(SUCCEEDED(hr)),
3246 "Partial block lock %s, expected %s, format %s, pool %s\n",
3247 SUCCEEDED(hr) ? "succeeded" : "failed", pools[j].success ? "success" : "failure",
3248 formats[i].name, pools[j].name);
3249 if (SUCCEEDED(hr))
3251 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3252 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3255 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height >> 1);
3256 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3257 ok(SUCCEEDED(hr) == pools[j].success || broken(SUCCEEDED(hr)),
3258 "Partial block lock %s, expected %s, format %s, pool %s\n",
3259 SUCCEEDED(hr) ? "succeeded" : "failed", pools[j].success ? "success" : "failure",
3260 formats[i].name, pools[j].name);
3261 if (SUCCEEDED(hr))
3263 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3264 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3268 SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height);
3269 hr = IDirectDrawSurface7_Lock(surface, &rect, &ddsd, 0, NULL);
3270 ok(SUCCEEDED(hr), "Full block lock returned %08x, expected %08x, format %s, pool %s\n",
3271 hr, DD_OK, formats[i].name, pools[j].name);
3272 if (SUCCEEDED(hr))
3274 hr = IDirectDrawSurface7_Unlock(surface, NULL);
3275 ok(SUCCEEDED(hr), "Unlock failed, hr %#x.\n", hr);
3278 IDirectDrawSurface7_Release(surface);
3282 IDirectDraw7_Release(dd7);
3285 static void create_surface_test(void)
3287 HRESULT hr;
3288 IDirectDraw2 *ddraw2;
3289 IDirectDraw4 *ddraw4;
3290 IDirectDraw7 *ddraw7;
3291 IDirectDrawSurface *surface;
3292 IDirectDrawSurface4 *surface4;
3293 IDirectDrawSurface7 *surface7;
3295 hr = IDirectDraw_CreateSurface(lpDD, NULL, &surface, NULL);
3296 ok(hr == DDERR_INVALIDPARAMS, "CreateSurface(ddsd=NULL) returned %#x,"
3297 " expected %#x.\n", hr, DDERR_INVALIDPARAMS);
3299 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &ddraw2);
3300 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3302 hr = IDirectDraw2_CreateSurface(ddraw2, NULL, &surface, NULL);
3303 ok(hr == DDERR_INVALIDPARAMS, "CreateSurface(ddsd=NULL) returned %#x,"
3304 " expected %#x.\n", hr, DDERR_INVALIDPARAMS);
3306 IDirectDraw2_Release(ddraw2);
3308 hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &ddraw4);
3309 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3311 hr = IDirectDraw4_CreateSurface(ddraw4, NULL, &surface4, NULL);
3312 ok(hr == DDERR_INVALIDPARAMS, "CreateSurface(ddsd=NULL) returned %#x,"
3313 " expected %#x.\n", hr, DDERR_INVALIDPARAMS);
3315 IDirectDraw4_Release(ddraw4);
3317 if (!pDirectDrawCreateEx)
3319 skip("DirectDrawCreateEx not available, skipping IDirectDraw7 tests.\n");
3320 return;
3322 hr = pDirectDrawCreateEx(NULL, (void **) &ddraw7, &IID_IDirectDraw7, NULL);
3323 ok(SUCCEEDED(hr), "DirectDrawCreateEx failed, hr %#x.\n", hr);
3325 hr = IDirectDraw7_CreateSurface(ddraw7, NULL, &surface7, NULL);
3326 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "CreateSurface(ddsd=NULL, pre-SCL) returned %#x,"
3327 " expected %#x.\n", hr, DDERR_NOCOOPERATIVELEVELSET);
3329 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, NULL, DDSCL_NORMAL);
3330 ok(hr == DD_OK, "SetCooperativeLevel failed, hr %#x.\n", hr);
3332 hr = IDirectDraw7_CreateSurface(ddraw7, NULL, &surface7, NULL);
3333 ok(hr == DDERR_INVALIDPARAMS, "CreateSurface(ddsd=NULL) returned %#x,"
3334 " expected %#x.\n", hr, DDERR_INVALIDPARAMS);
3336 IDirectDraw7_Release(ddraw7);
3339 START_TEST(dsurface)
3341 HRESULT ret;
3342 IDirectDraw4 *dd4;
3344 HMODULE ddraw_mod = GetModuleHandleA("ddraw.dll");
3345 pDirectDrawCreateEx = (void *) GetProcAddress(ddraw_mod, "DirectDrawCreateEx");
3347 if (!CreateDirectDraw())
3348 return;
3350 ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3351 if (ret == E_NOINTERFACE)
3353 win_skip("DirectDraw4 and higher are not supported\n");
3354 ReleaseDirectDraw();
3355 return;
3357 IDirectDraw_Release(dd4);
3359 if(!can_create_primary_surface())
3361 skip("Unable to create primary surface\n");
3362 return;
3365 ddcaps.dwSize = sizeof(DDCAPS);
3366 ret = IDirectDraw_GetCaps(lpDD, &ddcaps, NULL);
3367 if (ret != DD_OK)
3369 skip("IDirectDraw_GetCaps failed with %08x\n", ret);
3370 return;
3373 SrcColorKey32BlitTest();
3374 QueryInterface();
3375 GetDDInterface_1();
3376 GetDDInterface_2();
3377 GetDDInterface_4();
3378 GetDDInterface_7();
3379 EnumTest();
3380 CubeMapTest();
3381 CompressedTest();
3382 SizeTest();
3383 BltParamTest();
3384 StructSizeTest();
3385 PaletteTest();
3386 SurfaceCapsTest();
3387 GetDCTest();
3388 BackBufferCreateSurfaceTest();
3389 BackBufferAttachmentFlipTest();
3390 CreateSurfaceBadCapsSizeTest();
3391 no_ddsd_caps_test();
3392 zbufferbitdepth_test();
3393 pixelformat_flag_test();
3394 partial_block_lock_test();
3395 create_surface_test();
3396 ReleaseDirectDraw();