2 * Copyright 2011-2012 Henri Verbeet for CodeWeavers
3 * Copyright 2012-2014 Stefan Dösinger for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/test.h"
24 struct create_window_thread_param
27 HANDLE window_created
;
28 HANDLE destroy_window
;
32 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
34 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
36 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
38 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
40 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
44 static DWORD WINAPI
create_window_thread_proc(void *param
)
46 struct create_window_thread_param
*p
= param
;
50 p
->window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
51 0, 0, 640, 480, 0, 0, 0, 0);
52 ret
= SetEvent(p
->window_created
);
53 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
59 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
60 DispatchMessageA(&msg
);
61 res
= WaitForSingleObject(p
->destroy_window
, 100);
62 if (res
== WAIT_OBJECT_0
)
64 if (res
!= WAIT_TIMEOUT
)
66 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
71 DestroyWindow(p
->window
);
76 static void create_window_thread(struct create_window_thread_param
*p
)
80 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
81 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
82 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
83 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
84 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
85 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
86 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
87 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
90 static void destroy_window_thread(struct create_window_thread_param
*p
)
92 SetEvent(p
->destroy_window
);
93 WaitForSingleObject(p
->thread
, INFINITE
);
94 CloseHandle(p
->destroy_window
);
95 CloseHandle(p
->window_created
);
96 CloseHandle(p
->thread
);
99 static IDirectDrawSurface
*get_depth_stencil(IDirect3DDevice2
*device
)
101 IDirectDrawSurface
*rt
, *ret
;
102 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
105 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
106 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
107 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ret
);
108 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
109 IDirectDrawSurface_Release(rt
);
113 static D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
115 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
116 DDSURFACEDESC surface_desc
;
120 memset(&surface_desc
, 0, sizeof(surface_desc
));
121 surface_desc
.dwSize
= sizeof(surface_desc
);
123 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
124 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
128 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
130 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
131 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
136 static HRESULT CALLBACK
enum_z_fmt(GUID
*guid
, char *description
, char *name
,
137 D3DDEVICEDESC
*hal_desc
, D3DDEVICEDESC
*hel_desc
, void *ctx
)
139 DWORD
*z_depth
= ctx
;
141 if (!IsEqualGUID(&IID_IDirect3DHALDevice
, guid
))
142 return D3DENUMRET_OK
;
144 if (hal_desc
->dwDeviceZBufferBitDepth
& DDBD_32
)
146 else if (hal_desc
->dwDeviceZBufferBitDepth
& DDBD_24
)
148 else if (hal_desc
->dwDeviceZBufferBitDepth
& DDBD_16
)
154 static IDirectDraw2
*create_ddraw(void)
156 IDirectDraw2
*ddraw2
;
160 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
163 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw2
);
164 IDirectDraw_Release(ddraw1
);
171 static IDirect3DDevice2
*create_device(IDirectDraw2
*ddraw
, HWND window
, DWORD coop_level
)
173 IDirectDrawSurface
*surface
, *ds
;
174 IDirect3DDevice2
*device
= NULL
;
175 DDSURFACEDESC surface_desc
;
180 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, coop_level
);
181 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
183 memset(&surface_desc
, 0, sizeof(surface_desc
));
184 surface_desc
.dwSize
= sizeof(surface_desc
);
185 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
186 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
187 surface_desc
.dwWidth
= 640;
188 surface_desc
.dwHeight
= 480;
190 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
191 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
193 if (coop_level
& DDSCL_NORMAL
)
195 IDirectDrawClipper
*clipper
;
197 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
198 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
199 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
200 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
201 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
202 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
203 IDirectDrawClipper_Release(clipper
);
206 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
209 IDirectDrawSurface_Release(surface
);
213 hr
= IDirect3D2_EnumDevices(d3d
, enum_z_fmt
, &z_depth
);
214 ok(SUCCEEDED(hr
), "Failed to enumerate z-formats, hr %#x.\n", hr
);
215 if (FAILED(hr
) || !z_depth
)
217 IDirect3D2_Release(d3d
);
218 IDirectDrawSurface_Release(surface
);
222 memset(&surface_desc
, 0, sizeof(surface_desc
));
223 surface_desc
.dwSize
= sizeof(surface_desc
);
224 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
225 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
226 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
227 surface_desc
.dwWidth
= 640;
228 surface_desc
.dwHeight
= 480;
229 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
230 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
233 IDirect3D2_Release(d3d
);
234 IDirectDrawSurface_Release(surface
);
238 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
239 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
240 IDirectDrawSurface_Release(ds
);
243 IDirect3D2_Release(d3d
);
244 IDirectDrawSurface_Release(surface
);
248 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
249 IDirect3D2_Release(d3d
);
250 IDirectDrawSurface_Release(surface
);
257 static IDirect3DViewport2
*create_viewport(IDirect3DDevice2
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
259 IDirect3DViewport2
*viewport
;
264 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
265 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
266 hr
= IDirect3D2_CreateViewport(d3d
, &viewport
, NULL
);
267 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
268 hr
= IDirect3DDevice2_AddViewport(device
, viewport
);
269 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
270 memset(&vp
, 0, sizeof(vp
));
271 vp
.dwSize
= sizeof(vp
);
278 vp
.dvClipWidth
= 2.0f
;
279 vp
.dvClipHeight
= 2.0f
;
282 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp
);
283 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
284 IDirect3D2_Release(d3d
);
289 static void viewport_set_background(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
,
290 IDirect3DMaterial2
*material
)
292 D3DMATERIALHANDLE material_handle
;
295 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &material_handle
);
296 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
297 hr
= IDirect3DViewport2_SetBackground(viewport
, material_handle
);
298 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
301 static void destroy_viewport(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
)
305 hr
= IDirect3DDevice2_DeleteViewport(device
, viewport
);
306 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
307 IDirect3DViewport2_Release(viewport
);
310 static IDirect3DMaterial2
*create_diffuse_material(IDirect3DDevice2
*device
, float r
, float g
, float b
, float a
)
312 IDirect3DMaterial2
*material
;
317 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
318 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
319 hr
= IDirect3D2_CreateMaterial(d3d
, &material
, NULL
);
320 ok(SUCCEEDED(hr
), "Failed to create material, hr %#x.\n", hr
);
321 memset(&mat
, 0, sizeof(mat
));
322 mat
.dwSize
= sizeof(mat
);
323 U1(U(mat
).diffuse
).r
= r
;
324 U2(U(mat
).diffuse
).g
= g
;
325 U3(U(mat
).diffuse
).b
= b
;
326 U4(U(mat
).diffuse
).a
= a
;
327 hr
= IDirect3DMaterial2_SetMaterial(material
, &mat
);
328 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
329 IDirect3D2_Release(d3d
);
334 static void destroy_material(IDirect3DMaterial2
*material
)
336 IDirect3DMaterial2_Release(material
);
339 static const UINT
*expect_messages
;
341 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
343 if (expect_messages
&& message
== *expect_messages
)
346 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
349 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
350 * interface. This prevents subsequent SetCooperativeLevel() calls on a
351 * different window from failing with DDERR_HWNDALREADYSET. */
352 static void fix_wndproc(HWND window
, LONG_PTR proc
)
357 if (!(ddraw
= create_ddraw()))
360 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
361 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
362 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
363 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
364 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
366 IDirectDraw2_Release(ddraw
);
369 static HRESULT CALLBACK
restore_callback(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
371 HRESULT hr
= IDirectDrawSurface_Restore(surface
);
372 ok(SUCCEEDED(hr
), "Failed to restore surface, hr %#x.\n", hr
);
373 IDirectDrawSurface_Release(surface
);
378 static HRESULT
restore_surfaces(IDirectDraw2
*ddraw
)
380 return IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
,
381 NULL
, NULL
, restore_callback
);
384 static void test_coop_level_create_device_window(void)
386 HWND focus_window
, device_window
;
390 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
391 0, 0, 640, 480, 0, 0, 0, 0);
392 if (!(ddraw
= create_ddraw()))
394 skip("Failed to create a ddraw object, skipping test.\n");
395 DestroyWindow(focus_window
);
399 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
400 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
401 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
402 ok(!device_window
, "Unexpected device window found.\n");
403 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
404 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
405 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
406 ok(!device_window
, "Unexpected device window found.\n");
407 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
408 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
409 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
410 ok(!device_window
, "Unexpected device window found.\n");
411 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
412 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
413 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
414 ok(!device_window
, "Unexpected device window found.\n");
415 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
416 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
417 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
418 ok(!device_window
, "Unexpected device window found.\n");
420 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
421 if (broken(hr
== DDERR_INVALIDPARAMS
))
423 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
424 IDirectDraw2_Release(ddraw
);
425 DestroyWindow(focus_window
);
429 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
430 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
431 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
432 ok(!device_window
, "Unexpected device window found.\n");
433 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
434 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
435 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
436 ok(!device_window
, "Unexpected device window found.\n");
438 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
439 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
440 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
441 ok(!device_window
, "Unexpected device window found.\n");
442 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
443 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
444 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
445 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
446 ok(!!device_window
, "Device window not found.\n");
448 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
449 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
450 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
451 ok(!device_window
, "Unexpected device window found.\n");
452 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
453 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
454 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
455 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
456 ok(!!device_window
, "Device window not found.\n");
458 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
459 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
460 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
461 ok(!device_window
, "Unexpected device window found.\n");
462 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
463 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
464 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
465 ok(!device_window
, "Unexpected device window found.\n");
466 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
467 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
468 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
469 ok(!device_window
, "Unexpected device window found.\n");
470 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
471 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
472 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
473 ok(!!device_window
, "Device window not found.\n");
475 IDirectDraw2_Release(ddraw
);
476 DestroyWindow(focus_window
);
479 static void test_clipper_blt(void)
481 IDirectDrawSurface
*src_surface
, *dst_surface
;
482 RECT client_rect
, src_rect
;
483 IDirectDrawClipper
*clipper
;
484 DDSURFACEDESC surface_desc
;
485 unsigned int i
, j
, x
, y
;
496 static const DWORD src_data
[] =
498 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
499 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
500 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
502 static const D3DCOLOR expected1
[] =
504 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
505 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
506 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
507 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
509 static const D3DCOLOR expected2
[] =
511 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
512 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
513 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
514 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
517 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
518 10, 10, 640, 480, 0, 0, 0, 0);
519 ShowWindow(window
, SW_SHOW
);
520 if (!(ddraw
= create_ddraw()))
522 skip("Failed to create a ddraw object, skipping test.\n");
523 DestroyWindow(window
);
527 ret
= GetClientRect(window
, &client_rect
);
528 ok(ret
, "Failed to get client rect.\n");
529 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
530 ok(ret
, "Failed to map client rect.\n");
532 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
533 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
535 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
536 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
537 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
538 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
539 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
540 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
541 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
542 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
543 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
544 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
545 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
546 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
547 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
548 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
549 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
550 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
551 rgn_data
->rdh
.rcBound
.left
, rgn_data
->rdh
.rcBound
.top
,
552 rgn_data
->rdh
.rcBound
.right
, rgn_data
->rdh
.rcBound
.bottom
,
553 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
554 HeapFree(GetProcessHeap(), 0, rgn_data
);
556 r1
= CreateRectRgn(0, 0, 320, 240);
557 ok(!!r1
, "Failed to create region.\n");
558 r2
= CreateRectRgn(320, 240, 640, 480);
559 ok(!!r2
, "Failed to create region.\n");
560 CombineRgn(r1
, r1
, r2
, RGN_OR
);
561 ret
= GetRegionData(r1
, 0, NULL
);
562 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
563 ret
= GetRegionData(r1
, ret
, rgn_data
);
564 ok(!!ret
, "Failed to get region data.\n");
569 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
570 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
571 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
572 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
573 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
574 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
576 HeapFree(GetProcessHeap(), 0, rgn_data
);
578 memset(&surface_desc
, 0, sizeof(surface_desc
));
579 surface_desc
.dwSize
= sizeof(surface_desc
);
580 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
581 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
582 surface_desc
.dwWidth
= 640;
583 surface_desc
.dwHeight
= 480;
584 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
585 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
586 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
587 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
588 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
589 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
591 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
592 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
593 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
594 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
596 memset(&fx
, 0, sizeof(fx
));
597 fx
.dwSize
= sizeof(fx
);
598 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
599 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
600 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
601 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
603 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
604 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
605 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
606 ptr
= surface_desc
.lpSurface
;
607 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
608 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
609 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
610 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
611 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
613 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
614 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
616 SetRect(&src_rect
, 1, 1, 5, 2);
617 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
618 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
619 for (i
= 0; i
< 4; ++i
)
621 for (j
= 0; j
< 4; ++j
)
623 x
= 80 * ((2 * j
) + 1);
624 y
= 60 * ((2 * i
) + 1);
625 color
= get_surface_color(dst_surface
, x
, y
);
626 ok(compare_color(color
, expected1
[i
* 4 + j
], 1),
627 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
631 U5(fx
).dwFillColor
= 0xff0000ff;
632 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
633 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
634 for (i
= 0; i
< 4; ++i
)
636 for (j
= 0; j
< 4; ++j
)
638 x
= 80 * ((2 * j
) + 1);
639 y
= 60 * ((2 * i
) + 1);
640 color
= get_surface_color(dst_surface
, x
, y
);
641 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
642 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
646 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
647 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#x.\n", hr
);
649 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
650 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
651 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
652 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
653 DestroyWindow(window
);
654 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
655 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
656 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
657 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
658 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
659 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
660 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
661 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
662 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
663 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
664 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
665 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
667 IDirectDrawSurface_Release(dst_surface
);
668 IDirectDrawSurface_Release(src_surface
);
669 IDirectDrawClipper_Release(clipper
);
670 IDirectDraw2_Release(ddraw
);
673 static void test_coop_level_d3d_state(void)
675 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
676 IDirectDrawSurface
*rt
, *surface
;
677 IDirect3DMaterial2
*background
;
678 IDirect3DViewport2
*viewport
;
679 IDirect3DDevice2
*device
;
680 D3DMATERIAL material
;
687 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
688 0, 0, 640, 480, 0, 0, 0, 0);
689 if (!(ddraw
= create_ddraw()))
691 skip("Failed to create a ddraw object, skipping test.\n");
692 DestroyWindow(window
);
695 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
697 skip("Failed to create a 3D device, skipping test.\n");
698 IDirectDraw2_Release(ddraw
);
699 DestroyWindow(window
);
703 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
704 viewport
= create_viewport(device
, 0, 0, 640, 480);
705 viewport_set_background(device
, viewport
, background
);
707 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
708 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
709 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
710 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
711 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
712 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
713 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
714 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
715 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
716 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
717 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
718 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
719 color
= get_surface_color(rt
, 320, 240);
720 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
722 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
723 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
724 hr
= IDirectDrawSurface_IsLost(rt
);
725 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
726 hr
= restore_surfaces(ddraw
);
727 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
729 memset(&material
, 0, sizeof(material
));
730 material
.dwSize
= sizeof(material
);
731 U1(U(material
).diffuse
).r
= 0.0f
;
732 U2(U(material
).diffuse
).g
= 1.0f
;
733 U3(U(material
).diffuse
).b
= 0.0f
;
734 U4(U(material
).diffuse
).a
= 1.0f
;
735 hr
= IDirect3DMaterial2_SetMaterial(background
, &material
);
736 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
738 hr
= IDirect3DDevice2_GetRenderTarget(device
, &surface
);
739 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
740 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
741 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
742 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
743 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
744 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
745 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
746 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
747 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
748 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
749 color
= get_surface_color(rt
, 320, 240);
750 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
752 destroy_viewport(device
, viewport
);
753 destroy_material(background
);
754 IDirectDrawSurface_Release(surface
);
755 IDirectDrawSurface_Release(rt
);
756 IDirect3DDevice2_Release(device
);
757 IDirectDraw2_Release(ddraw
);
758 DestroyWindow(window
);
761 static void test_surface_interface_mismatch(void)
763 IDirectDraw2
*ddraw
= NULL
;
764 IDirect3D2
*d3d
= NULL
;
765 IDirectDrawSurface
*surface
= NULL
, *ds
;
766 IDirectDrawSurface3
*surface3
= NULL
;
767 IDirect3DDevice2
*device
= NULL
;
768 IDirect3DViewport2
*viewport
= NULL
;
769 IDirect3DMaterial2
*background
= NULL
;
770 DDSURFACEDESC surface_desc
;
776 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
778 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
779 0, 0, 640, 480, 0, 0, 0, 0);
781 if (!(ddraw
= create_ddraw()))
783 skip("Failed to create a ddraw object, skipping test.\n");
787 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
788 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
790 memset(&surface_desc
, 0, sizeof(surface_desc
));
791 surface_desc
.dwSize
= sizeof(surface_desc
);
792 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
793 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
794 surface_desc
.dwWidth
= 640;
795 surface_desc
.dwHeight
= 480;
797 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
798 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
800 hr
= IDirectDrawSurface2_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
803 skip("Failed to get the IDirectDrawSurface3 interface, skipping test.\n");
807 if (FAILED(hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
809 skip("D3D interface is not available, skipping test.\n");
813 hr
= IDirect3D2_EnumDevices(d3d
, enum_z_fmt
, &z_depth
);
814 if (FAILED(hr
) || !z_depth
)
816 skip("No depth buffer formats available, skipping test.\n");
820 memset(&surface_desc
, 0, sizeof(surface_desc
));
821 surface_desc
.dwSize
= sizeof(surface_desc
);
822 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
823 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
824 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
825 surface_desc
.dwWidth
= 640;
826 surface_desc
.dwHeight
= 480;
827 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
828 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
832 /* Using a different surface interface version still works */
833 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
834 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
835 refcount
= IDirectDrawSurface_Release(ds
);
836 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
841 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface
*)surface3
, &device
);
842 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
846 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
847 viewport
= create_viewport(device
, 0, 0, 640, 480);
848 viewport_set_background(device
, viewport
, background
);
850 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
851 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
852 color
= get_surface_color(surface
, 320, 240);
853 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
857 destroy_viewport(device
, viewport
);
859 destroy_material(background
);
860 if (surface3
) IDirectDrawSurface3_Release(surface3
);
861 if (surface
) IDirectDrawSurface_Release(surface
);
862 if (device
) IDirect3DDevice2_Release(device
);
863 if (d3d
) IDirect3D2_Release(d3d
);
864 if (ddraw
) IDirectDraw2_Release(ddraw
);
865 DestroyWindow(window
);
868 static void test_coop_level_threaded(void)
870 struct create_window_thread_param p
;
874 if (!(ddraw
= create_ddraw()))
876 skip("Failed to create a ddraw object, skipping test.\n");
879 create_window_thread(&p
);
881 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
882 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
884 IDirectDraw2_Release(ddraw
);
885 destroy_window_thread(&p
);
888 static void test_depth_blit(void)
890 static D3DLVERTEX quad1
[] =
892 {{-1.0}, { 1.0}, {0.50f
}, 0, {0xff00ff00}},
893 {{ 1.0}, { 1.0}, {0.50f
}, 0, {0xff00ff00}},
894 {{-1.0}, {-1.0}, {0.50f
}, 0, {0xff00ff00}},
895 {{ 1.0}, {-1.0}, {0.50f
}, 0, {0xff00ff00}},
897 static const D3DCOLOR expected_colors
[4][4] =
899 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
900 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
901 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
902 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
904 DDSURFACEDESC ddsd_new
, ddsd_existing
;
906 IDirect3DDevice2
*device
;
907 IDirectDrawSurface
*ds1
, *ds2
, *ds3
, *rt
;
908 IDirect3DViewport2
*viewport
;
909 RECT src_rect
, dst_rect
;
917 IDirect3DMaterial2
*background
;
919 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
920 0, 0, 640, 480, 0, 0, 0, 0);
921 if (!(ddraw
= create_ddraw()))
923 skip("Failed to create a ddraw object, skipping test.\n");
924 DestroyWindow(window
);
927 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
929 skip("Failed to create a 3D device, skipping test.\n");
930 IDirectDraw2_Release(ddraw
);
931 DestroyWindow(window
);
935 ds1
= get_depth_stencil(device
);
937 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
938 ddsd_new
.dwSize
= sizeof(ddsd_new
);
939 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
940 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
941 hr
= IDirectDrawSurface_GetSurfaceDesc(ds1
, &ddsd_existing
);
942 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
943 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
944 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
945 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
946 ddsd_new
.ddpfPixelFormat
= ddsd_existing
.ddpfPixelFormat
;
947 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
948 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
949 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
950 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
952 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
953 viewport
= create_viewport(device
, 0, 0, ddsd_existing
.dwWidth
, ddsd_existing
.dwHeight
);
954 viewport_set_background(device
, viewport
, background
);
955 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
956 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
958 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
959 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
960 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
961 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
963 U1(d3drect
).x1
= U2(d3drect
).y1
= 0;
964 U3(d3drect
).x2
= ddsd_existing
.dwWidth
; U4(d3drect
).y2
= ddsd_existing
.dwHeight
;
965 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
);
966 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
969 SetRect(&src_rect
, 0, 0, 320, 240);
970 SetRect(&dst_rect
, 0, 0, 320, 240);
971 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
972 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
973 /* Different locations. */
974 SetRect(&src_rect
, 0, 0, 320, 240);
975 SetRect(&dst_rect
, 320, 240, 640, 480);
976 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
977 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
979 SetRect(&src_rect
, 0, 0, 320, 240);
980 SetRect(&dst_rect
, 0, 0, 640, 480);
981 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
982 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
984 SetRect(&src_rect
, 0, 480, 640, 0);
985 SetRect(&dst_rect
, 0, 0, 640, 480);
986 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
987 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
988 SetRect(&src_rect
, 0, 0, 640, 480);
989 SetRect(&dst_rect
, 0, 480, 640, 0);
990 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
991 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
992 /* Full, explicit. */
993 SetRect(&src_rect
, 0, 0, 640, 480);
994 SetRect(&dst_rect
, 0, 0, 640, 480);
995 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
996 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
997 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
999 /* Depth blit inside a BeginScene / EndScene pair */
1000 hr
= IDirect3DDevice2_BeginScene(device
);
1001 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1002 /* From the current depth stencil */
1003 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1004 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1005 /* To the current depth stencil */
1006 hr
= IDirectDrawSurface_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1007 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1008 /* Between unbound surfaces */
1009 hr
= IDirectDrawSurface_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1010 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1011 hr
= IDirect3DDevice2_EndScene(device
);
1012 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1014 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1015 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1016 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1017 * a reliable result(z = 0.0) */
1018 memset(&fx
, 0, sizeof(fx
));
1019 fx
.dwSize
= sizeof(fx
);
1020 U5(fx
).dwFillDepth
= 0;
1021 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1022 ok(SUCCEEDED(hr
), "Failed to clear the source z buffer, hr %#x.\n", hr
);
1024 /* This clears the Z buffer with 1.0 */
1025 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
);
1026 ok(SUCCEEDED(hr
), "Failed to clear the color and z buffers, hr %#x.\n", hr
);
1028 SetRect(&dst_rect
, 0, 0, 320, 240);
1029 hr
= IDirectDrawSurface_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1030 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1031 IDirectDrawSurface_Release(ds3
);
1032 IDirectDrawSurface_Release(ds2
);
1033 IDirectDrawSurface_Release(ds1
);
1035 hr
= IDirect3DDevice2_BeginScene(device
);
1036 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1037 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad1
, 4, 0);
1038 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1039 hr
= IDirect3DDevice2_EndScene(device
);
1040 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1042 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1043 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1044 for (i
= 0; i
< 4; ++i
)
1046 for (j
= 0; j
< 4; ++j
)
1048 unsigned int x
= 80 * ((2 * j
) + 1);
1049 unsigned int y
= 60 * ((2 * i
) + 1);
1050 color
= get_surface_color(rt
, x
, y
);
1051 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1052 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1055 IDirectDrawSurface_Release(rt
);
1057 destroy_viewport(device
, viewport
);
1058 destroy_material(background
);
1059 IDirect3DDevice2_Release(device
);
1060 IDirectDraw2_Release(ddraw
);
1061 DestroyWindow(window
);
1064 static void test_texture_load_ckey(void)
1066 IDirectDraw2
*ddraw
= NULL
;
1067 IDirectDrawSurface
*src
= NULL
;
1068 IDirectDrawSurface
*dst
= NULL
;
1069 IDirect3DTexture
*src_tex
= NULL
;
1070 IDirect3DTexture
*dst_tex
= NULL
;
1075 if (!(ddraw
= create_ddraw()))
1077 skip("Failed to create a ddraw object, skipping test.\n");
1080 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1081 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1083 memset(&ddsd
, 0, sizeof(ddsd
));
1084 ddsd
.dwSize
= sizeof(ddsd
);
1085 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1086 ddsd
.dwHeight
= 128;
1088 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1089 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1090 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1091 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1092 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1093 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1095 hr
= IDirectDrawSurface_QueryInterface(src
, &IID_IDirect3DTexture
, (void **)&src_tex
);
1096 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get Direct3DTexture interface, hr %#x.\n", hr
);
1099 /* 64 bit ddraw does not support d3d */
1100 skip("Could not get Direct3DTexture interface, skipping texture::Load color keying tests.\n");
1103 hr
= IDirectDrawSurface_QueryInterface(dst
, &IID_IDirect3DTexture
, (void **)&dst_tex
);
1104 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture interface, hr %#x.\n", hr
);
1106 /* No surface has a color key */
1107 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1108 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDCAPS
), "Got unexpected hr %#x.\n", hr
);
1111 /* Testbot Windows NT VMs */
1112 skip("IDirect3DTexture::Load does not work, skipping color keying tests.\n");
1116 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1117 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1118 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1119 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1120 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1122 /* Source surface has a color key */
1123 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1124 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1125 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1126 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1127 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1128 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1129 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1130 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1131 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1133 /* Both surfaces have a color key: Dest ckey is overwritten */
1134 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1135 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1136 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1137 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1138 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1139 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1140 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1141 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1142 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1144 /* Only the destination has a color key: It is not deleted */
1145 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1146 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1147 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1148 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1149 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1150 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1151 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1152 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1153 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1154 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1157 if (dst_tex
) IDirect3DTexture_Release(dst_tex
);
1158 if (src_tex
) IDirect3DTexture_Release(src_tex
);
1159 if (dst
) IDirectDrawSurface_Release(dst
);
1160 if (src
) IDirectDrawSurface_Release(src
);
1161 if (ddraw
) IDirectDraw2_Release(ddraw
);
1164 static ULONG
get_refcount(IUnknown
*test_iface
)
1166 IUnknown_AddRef(test_iface
);
1167 return IUnknown_Release(test_iface
);
1170 static void test_viewport(void)
1172 IDirectDraw2
*ddraw
;
1175 ULONG ref
, old_d3d_ref
;
1176 IDirect3DViewport
*viewport
;
1177 IDirect3DViewport2
*viewport2
, *another_vp
, *test_vp
;
1178 IDirect3DViewport3
*viewport3
;
1179 IDirectDrawGammaControl
*gamma
;
1181 IDirect3DDevice2
*device
;
1184 if (!(ddraw
= create_ddraw()))
1186 skip("Failed to create a ddraw object, skipping test.\n");
1189 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1190 0, 0, 640, 480, 0, 0, 0, 0);
1191 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1193 skip("Failed to create a 3D device, skipping test.\n");
1194 IDirectDraw_Release(ddraw
);
1195 DestroyWindow(window
);
1199 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
1200 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get d3d interface, hr %#x.\n", hr
);
1203 skip("D3D interface is not available, skipping test.\n");
1204 IDirectDraw2_Release(ddraw
);
1207 old_d3d_ref
= get_refcount((IUnknown
*)d3d
);
1209 hr
= IDirect3D2_CreateViewport(d3d
, &viewport2
, NULL
);
1210 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1211 ref
= get_refcount((IUnknown
*)viewport2
);
1212 ok(ref
== 1, "Initial IDirect3DViewport2 refcount is %u\n", ref
);
1213 ref
= get_refcount((IUnknown
*)d3d
);
1214 ok(ref
== old_d3d_ref
, "IDirect3D2 refcount is %u\n", ref
);
1216 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1217 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1218 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
1219 ok(gamma
== NULL
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1220 if (SUCCEEDED(hr
)) IDirectDrawGammaControl_Release(gamma
);
1221 /* NULL iid: Segfaults */
1223 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport
, (void **)&viewport
);
1224 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport, hr %#x.\n", hr
);
1227 ref
= get_refcount((IUnknown
*)viewport
);
1228 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
1229 ref
= get_refcount((IUnknown
*)viewport2
);
1230 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
1231 IDirect3DViewport_Release(viewport
);
1235 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport3
, (void **)&viewport3
);
1236 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to QI IDirect3DViewport3, hr %#x.\n", hr
);
1239 ref
= get_refcount((IUnknown
*)viewport2
);
1240 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
1241 ref
= get_refcount((IUnknown
*)viewport3
);
1242 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1243 IDirect3DViewport3_Release(viewport3
);
1246 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IUnknown
, (void **)&unknown
);
1247 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#x.\n", hr
);
1250 ref
= get_refcount((IUnknown
*)viewport2
);
1251 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
1252 ref
= get_refcount(unknown
);
1253 ok(ref
== 2, "IUnknown refcount is %u\n", ref
);
1254 IUnknown_Release(unknown
);
1257 /* AddViewport(NULL): Segfault */
1258 hr
= IDirect3DDevice2_DeleteViewport(device
, NULL
);
1259 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1260 hr
= IDirect3DDevice2_GetCurrentViewport(device
, NULL
);
1261 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1263 hr
= IDirect3D2_CreateViewport(d3d
, &another_vp
, NULL
);
1264 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1266 /* Setting a viewport not in the viewport list fails */
1267 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1268 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1270 hr
= IDirect3DDevice2_AddViewport(device
, viewport2
);
1271 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1272 ref
= get_refcount((IUnknown
*) viewport2
);
1273 ok(ref
== 2, "viewport2 refcount is %d\n", ref
);
1274 hr
= IDirect3DDevice2_AddViewport(device
, another_vp
);
1275 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1276 ref
= get_refcount((IUnknown
*) another_vp
);
1277 ok(ref
== 2, "another_vp refcount is %d\n", ref
);
1279 test_vp
= (IDirect3DViewport2
*) 0xbaadc0de;
1280 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1281 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1282 ok(test_vp
== (IDirect3DViewport2
*) 0xbaadc0de, "Got unexpected pointer %p\n", test_vp
);
1284 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1285 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1286 ref
= get_refcount((IUnknown
*) viewport2
);
1287 ok(ref
== 3, "viewport2 refcount is %d\n", ref
);
1288 ref
= get_refcount((IUnknown
*) device
);
1289 ok(ref
== 1, "device refcount is %d\n", ref
);
1292 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1293 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1294 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1295 ref
= get_refcount((IUnknown
*) viewport2
);
1296 ok(ref
== 4, "viewport2 refcount is %d\n", ref
);
1297 if(test_vp
) IDirect3DViewport2_Release(test_vp
);
1299 /* GetCurrentViewport with a viewport set and NULL input param: Segfault */
1301 /* Cannot set the viewport to NULL */
1302 hr
= IDirect3DDevice2_SetCurrentViewport(device
, NULL
);
1303 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to set viewport to NULL, hr %#x.\n", hr
);
1305 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1306 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1307 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1308 if(test_vp
) IDirect3DViewport2_Release(test_vp
);
1310 /* SetCurrentViewport properly releases the old viewport's reference */
1311 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1312 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1313 ref
= get_refcount((IUnknown
*) viewport2
);
1314 ok(ref
== 2, "viewport2 refcount is %d\n", ref
);
1315 ref
= get_refcount((IUnknown
*) another_vp
);
1316 ok(ref
== 3, "another_vp refcount is %d\n", ref
);
1318 /* Deleting the viewport removes the reference added by AddViewport, but not
1319 * the one added by SetCurrentViewport. */
1320 hr
= IDirect3DDevice2_DeleteViewport(device
, another_vp
);
1321 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#x.\n", hr
);
1322 ref
= get_refcount((IUnknown
*) another_vp
);
1323 todo_wine
ok(ref
== 2, "IDirect3DViewport2 refcount is %d\n", ref
);
1325 /* GetCurrentViewport fails though */
1327 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1328 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1329 ok(test_vp
== NULL
, "Got unexpected viewport %p\n", test_vp
);
1330 if(test_vp
) IDirect3DViewport2_Release(test_vp
);
1332 /* Setting a different viewport does not free the leaked reference. How
1333 * do I get rid of it? Leak the viewport for now. */
1334 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1335 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1336 ref
= get_refcount((IUnknown
*) viewport2
);
1337 ok(ref
== 3, "viewport2 refcount is %d\n", ref
);
1338 ref
= get_refcount((IUnknown
*) another_vp
);
1339 todo_wine
ok(ref
== 2, "another_vp refcount is %d\n", ref
);
1341 /* Destroying the device removes the viewport, but does not free the reference
1342 * added by SetCurrentViewport. */
1343 IDirect3DDevice2_Release(device
);
1344 ref
= get_refcount((IUnknown
*) viewport2
);
1345 todo_wine
ok(ref
== 2, "viewport2 refcount is %d\n", ref
);
1347 IDirect3DViewport2_Release(another_vp
);
1348 IDirect3DViewport2_Release(viewport2
);
1349 IDirect3D2_Release(d3d
);
1350 DestroyWindow(window
);
1351 IDirectDraw2_Release(ddraw
);
1354 static void test_zenable(void)
1356 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1357 static D3DTLVERTEX tquad
[] =
1359 {{ 0.0f
}, {480.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1360 {{ 0.0f
}, { 0.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1361 {{640.0f
}, {480.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1362 {{640.0f
}, { 0.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1364 IDirect3DMaterial2
*background
;
1365 IDirect3DViewport2
*viewport
;
1366 IDirect3DDevice2
*device
;
1367 IDirectDrawSurface
*rt
;
1368 IDirectDraw2
*ddraw
;
1375 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1376 0, 0, 640, 480, 0, 0, 0, 0);
1377 if (!(ddraw
= create_ddraw()))
1379 skip("Failed to create a ddraw object, skipping test.\n");
1380 DestroyWindow(window
);
1383 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1385 skip("Failed to create a 3D device, skipping test.\n");
1386 IDirectDraw2_Release(ddraw
);
1387 DestroyWindow(window
);
1391 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1392 viewport
= create_viewport(device
, 0, 0, 640, 480);
1393 viewport_set_background(device
, viewport
, background
);
1394 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1395 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1397 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1398 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
1400 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1401 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1402 hr
= IDirect3DDevice2_BeginScene(device
);
1403 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1404 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, tquad
, 4, 0);
1405 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1406 hr
= IDirect3DDevice2_EndScene(device
);
1407 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1409 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1410 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1411 for (i
= 0; i
< 4; ++i
)
1413 for (j
= 0; j
< 4; ++j
)
1415 x
= 80 * ((2 * j
) + 1);
1416 y
= 60 * ((2 * i
) + 1);
1417 color
= get_surface_color(rt
, x
, y
);
1418 ok(compare_color(color
, 0x0000ff00, 1),
1419 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1422 IDirectDrawSurface_Release(rt
);
1424 destroy_viewport(device
, viewport
);
1425 destroy_material(background
);
1426 IDirect3DDevice2_Release(device
);
1427 IDirectDraw2_Release(ddraw
);
1428 DestroyWindow(window
);
1431 static void test_ck_rgba(void)
1433 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1434 static D3DTLVERTEX tquad
[] =
1436 {{ 0.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1437 {{ 0.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1438 {{640.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1439 {{640.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1440 {{ 0.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1441 {{ 0.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1442 {{640.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1443 {{640.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1447 D3DCOLOR fill_color
;
1455 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x000000ff},
1456 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x000000ff},
1457 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00},
1458 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1459 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00807f00},
1460 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x0000ff00},
1461 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00},
1462 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1465 D3DTEXTUREHANDLE texture_handle
;
1466 IDirect3DMaterial2
*background
;
1467 IDirectDrawSurface
*surface
;
1468 IDirect3DViewport2
*viewport
;
1469 IDirect3DTexture2
*texture
;
1470 DDSURFACEDESC surface_desc
;
1471 IDirect3DDevice2
*device
;
1472 IDirectDrawSurface
*rt
;
1473 IDirectDraw2
*ddraw
;
1480 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1481 0, 0, 640, 480, 0, 0, 0, 0);
1482 if (!(ddraw
= create_ddraw()))
1484 skip("Failed to create a ddraw object, skipping test.\n");
1485 DestroyWindow(window
);
1488 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1490 skip("Failed to create a 3D device, skipping test.\n");
1491 IDirectDraw2_Release(ddraw
);
1492 DestroyWindow(window
);
1496 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1497 viewport
= create_viewport(device
, 0, 0, 640, 480);
1498 viewport_set_background(device
, viewport
, background
);
1499 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1500 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1502 memset(&surface_desc
, 0, sizeof(surface_desc
));
1503 surface_desc
.dwSize
= sizeof(surface_desc
);
1504 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1505 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1506 surface_desc
.dwWidth
= 256;
1507 surface_desc
.dwHeight
= 256;
1508 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1509 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1510 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1511 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1512 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1513 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1514 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1515 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1516 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1517 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1518 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1519 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1520 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1521 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
1522 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1523 IDirect3DTexture2_Release(texture
);
1525 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1526 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1527 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1528 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1529 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1530 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1532 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1533 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1535 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
1537 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1538 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1539 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1540 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1542 memset(&fx
, 0, sizeof(fx
));
1543 fx
.dwSize
= sizeof(fx
);
1544 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1545 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1546 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1548 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
1549 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1550 hr
= IDirect3DDevice2_BeginScene(device
);
1551 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1552 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
1553 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1554 hr
= IDirect3DDevice2_EndScene(device
);
1555 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1557 color
= get_surface_color(rt
, 320, 240);
1559 todo_wine
ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1560 tests
[i
].result1
, i
, color
);
1562 ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1563 tests
[i
].result1
, i
, color
);
1565 U5(fx
).dwFillColor
= 0xff0000ff;
1566 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1567 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1569 hr
= IDirect3DDevice2_BeginScene(device
);
1570 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1571 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[4], 4, 0);
1572 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1573 hr
= IDirect3DDevice2_EndScene(device
);
1574 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1576 /* This tests that fragments that are masked out by the color key are
1577 * discarded, instead of just fully transparent. */
1578 color
= get_surface_color(rt
, 320, 240);
1580 todo_wine
ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1581 tests
[i
].result2
, i
, color
);
1583 ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1584 tests
[i
].result2
, i
, color
);
1587 IDirectDrawSurface_Release(rt
);
1588 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1589 ok(SUCCEEDED(hr
), "Failed to unset texture, hr %#x.\n", hr
);
1590 IDirectDrawSurface_Release(surface
);
1591 destroy_viewport(device
, viewport
);
1592 destroy_material(background
);
1593 IDirect3DDevice2_Release(device
);
1594 IDirectDraw2_Release(ddraw
);
1595 DestroyWindow(window
);
1598 static void test_ck_default(void)
1600 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1601 static D3DTLVERTEX tquad
[] =
1603 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1604 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1605 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1606 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1608 IDirectDrawSurface
*surface
, *rt
;
1609 D3DTEXTUREHANDLE texture_handle
;
1610 IDirect3DMaterial2
*background
;
1611 IDirect3DViewport2
*viewport
;
1612 DDSURFACEDESC surface_desc
;
1613 IDirect3DTexture2
*texture
;
1614 IDirect3DDevice2
*device
;
1615 IDirectDraw2
*ddraw
;
1622 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1623 0, 0, 640, 480, 0, 0, 0, 0);
1625 if (!(ddraw
= create_ddraw()))
1627 skip("Failed to create a ddraw object, skipping test.\n");
1628 DestroyWindow(window
);
1631 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1633 skip("Failed to create a 3D device, skipping test.\n");
1634 IDirectDraw2_Release(ddraw
);
1635 DestroyWindow(window
);
1639 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1640 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1642 background
= create_diffuse_material(device
, 0.0, 1.0f
, 0.0f
, 1.0f
);
1643 viewport
= create_viewport(device
, 0, 0, 640, 480);
1644 viewport_set_background(device
, viewport
, background
);
1645 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1646 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1648 memset(&surface_desc
, 0, sizeof(surface_desc
));
1649 surface_desc
.dwSize
= sizeof(surface_desc
);
1650 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1651 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1652 surface_desc
.dwWidth
= 256;
1653 surface_desc
.dwHeight
= 256;
1654 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1655 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1656 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1657 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1658 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1659 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1660 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
1661 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
1662 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1663 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1664 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1665 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1666 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
1667 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1668 IDirect3DTexture_Release(texture
);
1670 memset(&fx
, 0, sizeof(fx
));
1671 fx
.dwSize
= sizeof(fx
);
1672 U5(fx
).dwFillColor
= 0x000000ff;
1673 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1674 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
1676 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1677 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1678 hr
= IDirect3DDevice2_BeginScene(device
);
1679 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1680 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1681 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
1682 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1683 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1684 ok(!value
, "Got unexpected color keying state %#x.\n", value
);
1685 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
1686 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1687 hr
= IDirect3DDevice2_EndScene(device
);
1688 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1689 color
= get_surface_color(rt
, 320, 240);
1690 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1692 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1693 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1694 hr
= IDirect3DDevice2_BeginScene(device
);
1695 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1696 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
1697 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1698 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
1699 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1700 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1701 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1702 ok(!!value
, "Got unexpected color keying state %#x.\n", value
);
1703 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1704 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
1705 hr
= IDirect3DDevice2_EndScene(device
);
1706 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1707 color
= get_surface_color(rt
, 320, 240);
1708 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1710 IDirectDrawSurface_Release(surface
);
1711 destroy_viewport(device
, viewport
);
1712 destroy_material(background
);
1713 IDirectDrawSurface_Release(rt
);
1714 IDirect3DDevice2_Release(device
);
1715 IDirectDraw2_Release(ddraw
);
1716 DestroyWindow(window
);
1719 static void test_ck_complex(void)
1721 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
1722 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
1723 DDSURFACEDESC surface_desc
;
1724 IDirect3DDevice2
*device
;
1725 DDCOLORKEY color_key
;
1726 IDirectDraw2
*ddraw
;
1732 if (!(ddraw
= create_ddraw()))
1734 skip("Failed to create a ddraw object, skipping test.\n");
1738 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1739 0, 0, 640, 480, 0, 0, 0, 0);
1740 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
1742 skip("Failed to create a 3D device, skipping test.\n");
1743 DestroyWindow(window
);
1744 IDirectDraw2_Release(ddraw
);
1747 IDirect3DDevice2_Release(device
);
1749 memset(&surface_desc
, 0, sizeof(surface_desc
));
1750 surface_desc
.dwSize
= sizeof(surface_desc
);
1751 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1752 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
1753 surface_desc
.dwWidth
= 128;
1754 surface_desc
.dwHeight
= 128;
1755 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1756 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1758 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1759 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1760 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1761 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1762 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1763 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1764 memset(&color_key
, 0, sizeof(color_key
));
1765 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1766 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1767 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1768 color_key
.dwColorSpaceLowValue
);
1769 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1770 color_key
.dwColorSpaceHighValue
);
1773 IDirectDrawSurface_AddRef(mipmap
);
1774 for (i
= 0; i
< 7; ++i
)
1776 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
1777 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
1779 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1780 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
1781 color_key
.dwColorSpaceLowValue
= 0x000000ff;
1782 color_key
.dwColorSpaceHighValue
= 0x000000ff;
1783 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1784 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x, i %u.\n", hr
, i
);
1785 memset(&color_key
, 0, sizeof(color_key
));
1786 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1787 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x, i %u.\n", hr
, i
);
1788 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
1789 color_key
.dwColorSpaceLowValue
, i
);
1790 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
1791 color_key
.dwColorSpaceHighValue
, i
);
1793 IDirectDrawSurface_Release(mipmap
);
1797 memset(&color_key
, 0, sizeof(color_key
));
1798 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1799 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1800 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1801 color_key
.dwColorSpaceLowValue
);
1802 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1803 color_key
.dwColorSpaceHighValue
);
1805 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
1806 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
1807 IDirectDrawSurface_Release(mipmap
);
1808 refcount
= IDirectDrawSurface_Release(surface
);
1809 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1811 memset(&surface_desc
, 0, sizeof(surface_desc
));
1812 surface_desc
.dwSize
= sizeof(surface_desc
);
1813 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
1814 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
1815 surface_desc
.dwBackBufferCount
= 1;
1816 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1817 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1819 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1820 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1821 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1822 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1823 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1824 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1825 memset(&color_key
, 0, sizeof(color_key
));
1826 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1827 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1828 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1829 color_key
.dwColorSpaceLowValue
);
1830 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1831 color_key
.dwColorSpaceHighValue
);
1833 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
1834 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
1836 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1837 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
1838 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1839 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1840 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1841 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1842 memset(&color_key
, 0, sizeof(color_key
));
1843 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1844 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1845 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1846 color_key
.dwColorSpaceLowValue
);
1847 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1848 color_key
.dwColorSpaceHighValue
);
1850 IDirectDrawSurface_Release(tmp
);
1852 refcount
= IDirectDrawSurface_Release(surface
);
1853 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1854 refcount
= IDirectDraw2_Release(ddraw
);
1855 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1856 DestroyWindow(window
);
1862 REFIID refcount_iid
;
1866 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
1867 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
1869 ULONG refcount
, expected_refcount
;
1870 IUnknown
*iface1
, *iface2
;
1874 for (i
= 0; i
< entry_count
; ++i
)
1876 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
1877 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
1880 for (j
= 0; j
< entry_count
; ++j
)
1882 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
1883 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
1886 expected_refcount
= 0;
1887 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
1888 ++expected_refcount
;
1889 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
1890 ++expected_refcount
;
1891 refcount
= IUnknown_Release(iface2
);
1892 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
1893 refcount
, test_name
, i
, j
, expected_refcount
);
1897 expected_refcount
= 0;
1898 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
1899 ++expected_refcount
;
1900 refcount
= IUnknown_Release(iface1
);
1901 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
1902 refcount
, test_name
, i
, expected_refcount
);
1907 static void test_surface_qi(void)
1909 static const struct qi_test tests
[] =
1911 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
1912 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
1913 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
1914 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1915 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
1916 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
1917 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
1918 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
1919 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
1920 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
1921 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
1922 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
1923 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
1924 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
1925 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
1926 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
1927 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
1928 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
1929 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
1930 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
1931 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
1932 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
1933 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
1934 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
1935 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
1936 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
1937 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
1938 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
1939 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
1940 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
1941 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
1942 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
1943 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
1944 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
1945 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
1948 IDirectDrawSurface
*surface
;
1949 DDSURFACEDESC surface_desc
;
1950 IDirect3DDevice2
*device
;
1951 IDirectDraw2
*ddraw
;
1955 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
1957 win_skip("DirectDrawCreateEx not available, skipping test.\n");
1961 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1962 0, 0, 640, 480, 0, 0, 0, 0);
1963 if (!(ddraw
= create_ddraw()))
1965 skip("Failed to create a ddraw object, skipping test.\n");
1966 DestroyWindow(window
);
1969 /* Try to create a D3D device to see if the ddraw implementation supports
1970 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
1971 * doesn't support e.g. the IDirect3DTexture interfaces. */
1972 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1974 skip("Failed to create a 3D device, skipping test.\n");
1975 IDirectDraw2_Release(ddraw
);
1976 DestroyWindow(window
);
1979 IDirect3DDevice_Release(device
);
1981 memset(&surface_desc
, 0, sizeof(surface_desc
));
1982 surface_desc
.dwSize
= sizeof(surface_desc
);
1983 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1984 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1985 surface_desc
.dwWidth
= 512;
1986 surface_desc
.dwHeight
= 512;
1987 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1988 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1990 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface
, tests
, sizeof(tests
) / sizeof(*tests
));
1992 IDirectDrawSurface_Release(surface
);
1993 IDirectDraw2_Release(ddraw
);
1994 DestroyWindow(window
);
1997 static void test_device_qi(void)
1999 static const struct qi_test tests
[] =
2001 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
2002 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
2003 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
2004 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2005 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
2006 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
2007 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
2008 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
2009 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
2010 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
2011 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
2012 {&IID_IDirect3DDevice2
, &IID_IDirect3DDevice2
, S_OK
},
2013 {&IID_IDirect3DDevice
, &IID_IDirect3DDevice2
, S_OK
},
2014 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
2015 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
2016 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
2017 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
2018 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
2019 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
2020 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
2021 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
2022 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
2023 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
2024 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
2025 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
2026 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
2027 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
2028 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
2029 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
2030 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
2031 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
2032 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
2033 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
2034 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
2035 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
2036 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
2037 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
2038 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
2039 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
2040 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
2041 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
2042 {&IID_IUnknown
, &IID_IDirect3DDevice2
, S_OK
},
2045 IDirect3DDevice2
*device
;
2046 IDirectDraw2
*ddraw
;
2049 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2050 0, 0, 640, 480, 0, 0, 0, 0);
2051 if (!(ddraw
= create_ddraw()))
2053 skip("Failed to create a ddraw object, skipping test.\n");
2054 DestroyWindow(window
);
2057 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2059 skip("Failed to create a 3D device, skipping test.\n");
2060 IDirectDraw2_Release(ddraw
);
2061 DestroyWindow(window
);
2065 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice2
, tests
, sizeof(tests
) / sizeof(*tests
));
2067 IDirect3DDevice2_Release(device
);
2068 IDirectDraw2_Release(ddraw
);
2069 DestroyWindow(window
);
2072 static void test_wndproc(void)
2074 LONG_PTR proc
, ddraw_proc
;
2075 IDirectDraw2
*ddraw
;
2081 static const UINT messages
[] =
2083 WM_WINDOWPOSCHANGING
,
2086 WM_WINDOWPOSCHANGING
,
2092 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2093 if (!(ddraw
= create_ddraw()))
2095 skip("Failed to create a ddraw object, skipping test.\n");
2099 wc
.lpfnWndProc
= test_proc
;
2100 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2101 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2103 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2104 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2106 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2107 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2108 (LONG_PTR
)test_proc
, proc
);
2109 expect_messages
= messages
;
2110 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2111 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2112 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2113 expect_messages
= NULL
;
2114 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2115 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2116 (LONG_PTR
)test_proc
, proc
);
2117 ref
= IDirectDraw2_Release(ddraw
);
2118 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2119 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2120 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2121 (LONG_PTR
)test_proc
, proc
);
2123 /* DDSCL_NORMAL doesn't. */
2124 ddraw
= create_ddraw();
2125 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2126 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2127 (LONG_PTR
)test_proc
, proc
);
2128 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2129 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2130 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2131 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2132 (LONG_PTR
)test_proc
, proc
);
2133 ref
= IDirectDraw2_Release(ddraw
);
2134 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2135 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2136 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2137 (LONG_PTR
)test_proc
, proc
);
2139 /* The original window proc is only restored by ddraw if the current
2140 * window proc matches the one ddraw set. This also affects switching
2141 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2142 ddraw
= create_ddraw();
2143 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2144 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2145 (LONG_PTR
)test_proc
, proc
);
2146 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2147 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2148 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2149 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2150 (LONG_PTR
)test_proc
, proc
);
2152 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2153 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2154 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2155 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2156 (LONG_PTR
)test_proc
, proc
);
2157 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2158 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2159 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2160 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2161 (LONG_PTR
)test_proc
, proc
);
2162 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2163 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2164 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2165 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2166 (LONG_PTR
)DefWindowProcA
, proc
);
2167 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2168 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2169 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)ddraw_proc
);
2170 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2171 (LONG_PTR
)DefWindowProcA
, proc
);
2172 ref
= IDirectDraw2_Release(ddraw
);
2173 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2174 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2175 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2176 (LONG_PTR
)test_proc
, proc
);
2178 ddraw
= create_ddraw();
2179 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2180 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2181 (LONG_PTR
)test_proc
, proc
);
2182 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2183 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2184 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2185 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2186 (LONG_PTR
)test_proc
, proc
);
2187 ref
= IDirectDraw2_Release(ddraw
);
2188 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2189 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2190 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2191 (LONG_PTR
)DefWindowProcA
, proc
);
2193 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2194 expect_messages
= NULL
;
2195 DestroyWindow(window
);
2196 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2199 static void test_window_style(void)
2201 LONG style
, exstyle
, tmp
;
2202 RECT fullscreen_rect
, r
;
2203 IDirectDraw2
*ddraw
;
2208 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2209 0, 0, 100, 100, 0, 0, 0, 0);
2210 if (!(ddraw
= create_ddraw()))
2212 skip("Failed to create a ddraw object, skipping test.\n");
2213 DestroyWindow(window
);
2217 style
= GetWindowLongA(window
, GWL_STYLE
);
2218 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2219 SetRect(&fullscreen_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
2221 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2222 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2224 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2225 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2226 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2227 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2229 GetWindowRect(window
, &r
);
2230 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2231 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2232 r
.left
, r
.top
, r
.right
, r
.bottom
);
2233 GetClientRect(window
, &r
);
2234 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2236 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2237 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2239 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2240 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2241 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2242 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2244 ref
= IDirectDraw2_Release(ddraw
);
2245 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2247 DestroyWindow(window
);
2250 static void test_redundant_mode_set(void)
2252 DDSURFACEDESC surface_desc
= {0};
2253 IDirectDraw2
*ddraw
;
2259 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2260 0, 0, 100, 100, 0, 0, 0, 0);
2261 if (!(ddraw
= create_ddraw()))
2263 skip("Failed to create a ddraw object, skipping test.\n");
2264 DestroyWindow(window
);
2268 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2269 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2271 surface_desc
.dwSize
= sizeof(surface_desc
);
2272 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
2273 ok(SUCCEEDED(hr
), "GetDipslayMode failed, hr %#x.\n", hr
);
2275 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2276 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2277 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2279 GetWindowRect(window
, &r
);
2282 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2283 GetWindowRect(window
, &s
);
2284 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2285 r
.left
, r
.top
, r
.right
, r
.bottom
,
2286 s
.left
, s
.top
, s
.right
, s
.bottom
);
2288 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2289 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2290 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2292 GetWindowRect(window
, &s
);
2293 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2294 r
.left
, r
.top
, r
.right
, r
.bottom
,
2295 s
.left
, s
.top
, s
.right
, s
.bottom
);
2297 ref
= IDirectDraw2_Release(ddraw
);
2298 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2300 DestroyWindow(window
);
2303 static SIZE screen_size
, screen_size2
;
2305 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2307 if (message
== WM_SIZE
)
2309 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2310 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2313 return test_proc(hwnd
, message
, wparam
, lparam
);
2316 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2318 if (message
== WM_SIZE
)
2320 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2321 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2324 return test_proc(hwnd
, message
, wparam
, lparam
);
2327 static void test_coop_level_mode_set(void)
2329 IDirectDrawSurface
*primary
;
2330 RECT fullscreen_rect
, r
, s
;
2331 IDirectDraw2
*ddraw
;
2334 HWND window
, window2
;
2338 static const UINT exclusive_messages
[] =
2340 WM_WINDOWPOSCHANGING
,
2341 WM_WINDOWPOSCHANGED
,
2347 static const UINT normal_messages
[] =
2353 if (!(ddraw
= create_ddraw()))
2355 skip("Failed to create a ddraw object, skipping test.\n");
2358 wc
.lpfnWndProc
= mode_set_proc
;
2359 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2360 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2361 wc
.lpfnWndProc
= mode_set_proc2
;
2362 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
2363 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2365 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2366 0, 0, 100, 100, 0, 0, 0, 0);
2367 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2368 0, 0, 100, 100, 0, 0, 0, 0);
2370 SetRect(&fullscreen_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
2371 SetRect(&s
, 0, 0, 640, 480);
2373 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2374 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2376 GetWindowRect(window
, &r
);
2377 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2378 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2379 r
.left
, r
.top
, r
.right
, r
.bottom
);
2381 memset(&ddsd
, 0, sizeof(ddsd
));
2382 ddsd
.dwSize
= sizeof(ddsd
);
2383 ddsd
.dwFlags
= DDSD_CAPS
;
2384 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2386 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2387 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2388 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2389 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2390 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2391 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2392 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2393 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2395 GetWindowRect(window
, &r
);
2396 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2397 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2398 r
.left
, r
.top
, r
.right
, r
.bottom
);
2400 expect_messages
= exclusive_messages
;
2404 hr
= IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
2405 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2407 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2408 expect_messages
= NULL
;
2409 ok(screen_size
.cx
== s
.right
&& screen_size
.cy
== s
.bottom
,
2410 "Expected screen size %ux%u, got %ux%u.\n",
2411 s
.right
, s
.bottom
, screen_size
.cx
, screen_size
.cy
);
2413 GetWindowRect(window
, &r
);
2414 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2415 s
.left
, s
.top
, s
.right
, s
.bottom
,
2416 r
.left
, r
.top
, r
.right
, r
.bottom
);
2418 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2419 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2420 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2421 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2422 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2423 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2424 IDirectDrawSurface_Release(primary
);
2426 memset(&ddsd
, 0, sizeof(ddsd
));
2427 ddsd
.dwSize
= sizeof(ddsd
);
2428 ddsd
.dwFlags
= DDSD_CAPS
;
2429 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2431 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2432 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2433 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2434 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2435 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2436 s
.right
- s
.left
, ddsd
.dwWidth
);
2437 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2438 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2440 GetWindowRect(window
, &r
);
2441 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2442 s
.left
, s
.top
, s
.right
, s
.bottom
,
2443 r
.left
, r
.top
, r
.right
, r
.bottom
);
2445 expect_messages
= exclusive_messages
;
2449 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2450 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2452 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2453 expect_messages
= NULL
;
2454 ok(screen_size
.cx
== fullscreen_rect
.right
&& screen_size
.cy
== fullscreen_rect
.bottom
,
2455 "Expected screen size %ux%u, got %ux%u.\n",
2456 fullscreen_rect
.right
, fullscreen_rect
.bottom
, screen_size
.cx
, screen_size
.cy
);
2458 GetWindowRect(window
, &r
);
2459 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2460 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2461 r
.left
, r
.top
, r
.right
, r
.bottom
);
2463 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2464 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2465 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2466 s
.right
- s
.left
, ddsd
.dwWidth
);
2467 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2468 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2469 IDirectDrawSurface_Release(primary
);
2471 memset(&ddsd
, 0, sizeof(ddsd
));
2472 ddsd
.dwSize
= sizeof(ddsd
);
2473 ddsd
.dwFlags
= DDSD_CAPS
;
2474 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2476 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2477 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2478 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2479 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2480 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2481 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2482 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2483 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2485 GetWindowRect(window
, &r
);
2486 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2487 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2488 r
.left
, r
.top
, r
.right
, r
.bottom
);
2490 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2491 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2493 GetWindowRect(window
, &r
);
2494 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2495 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2496 r
.left
, r
.top
, r
.right
, r
.bottom
);
2498 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2499 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2500 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2501 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2502 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2503 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2504 IDirectDrawSurface_Release(primary
);
2506 memset(&ddsd
, 0, sizeof(ddsd
));
2507 ddsd
.dwSize
= sizeof(ddsd
);
2508 ddsd
.dwFlags
= DDSD_CAPS
;
2509 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2511 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2512 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2513 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2514 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2515 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2516 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2517 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2518 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2520 GetWindowRect(window
, &r
);
2521 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2522 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2523 r
.left
, r
.top
, r
.right
, r
.bottom
);
2525 expect_messages
= normal_messages
;
2529 hr
= IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
2530 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_NOEXCLUSIVEMODE
) /* NT4 testbot */,
2531 "SetDisplayMode failed, hr %#x.\n", hr
);
2532 if (hr
== DDERR_NOEXCLUSIVEMODE
)
2534 win_skip("Broken SetDisplayMode(), skipping remaining tests.\n");
2535 IDirectDrawSurface_Release(primary
);
2536 IDirectDraw2_Release(ddraw
);
2540 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2541 expect_messages
= NULL
;
2542 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2544 GetWindowRect(window
, &r
);
2545 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2546 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2547 r
.left
, r
.top
, r
.right
, r
.bottom
);
2549 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2550 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2551 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2552 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2553 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2554 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2555 IDirectDrawSurface_Release(primary
);
2557 memset(&ddsd
, 0, sizeof(ddsd
));
2558 ddsd
.dwSize
= sizeof(ddsd
);
2559 ddsd
.dwFlags
= DDSD_CAPS
;
2560 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2562 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2563 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2564 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2565 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2566 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2567 s
.right
- s
.left
, ddsd
.dwWidth
);
2568 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2569 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2571 GetWindowRect(window
, &r
);
2572 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2573 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2574 r
.left
, r
.top
, r
.right
, r
.bottom
);
2576 expect_messages
= normal_messages
;
2580 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2581 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2583 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2584 expect_messages
= NULL
;
2585 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2587 GetWindowRect(window
, &r
);
2588 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2589 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2590 r
.left
, r
.top
, r
.right
, r
.bottom
);
2592 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2593 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2594 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2595 s
.right
- s
.left
, ddsd
.dwWidth
);
2596 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2597 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2598 IDirectDrawSurface_Release(primary
);
2600 memset(&ddsd
, 0, sizeof(ddsd
));
2601 ddsd
.dwSize
= sizeof(ddsd
);
2602 ddsd
.dwFlags
= DDSD_CAPS
;
2603 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2605 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2606 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2607 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2608 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2609 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2610 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2611 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2612 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2614 GetWindowRect(window
, &r
);
2615 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2616 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2617 r
.left
, r
.top
, r
.right
, r
.bottom
);
2619 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
2620 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
2621 * not DDSCL_FULLSCREEN. */
2622 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2623 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2625 GetWindowRect(window
, &r
);
2626 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2627 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2628 r
.left
, r
.top
, r
.right
, r
.bottom
);
2630 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2631 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2632 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2633 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2634 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2635 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2636 IDirectDrawSurface_Release(primary
);
2638 memset(&ddsd
, 0, sizeof(ddsd
));
2639 ddsd
.dwSize
= sizeof(ddsd
);
2640 ddsd
.dwFlags
= DDSD_CAPS
;
2641 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2643 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2644 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2645 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2646 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2647 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2648 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2649 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2650 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2652 GetWindowRect(window
, &r
);
2653 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2654 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2655 r
.left
, r
.top
, r
.right
, r
.bottom
);
2657 expect_messages
= normal_messages
;
2661 hr
= IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
2662 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2664 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2665 expect_messages
= NULL
;
2666 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2668 GetWindowRect(window
, &r
);
2669 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2670 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2671 r
.left
, r
.top
, r
.right
, r
.bottom
);
2673 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2674 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2675 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2676 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2677 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2678 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2679 IDirectDrawSurface_Release(primary
);
2681 memset(&ddsd
, 0, sizeof(ddsd
));
2682 ddsd
.dwSize
= sizeof(ddsd
);
2683 ddsd
.dwFlags
= DDSD_CAPS
;
2684 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2686 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2687 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2688 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2689 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2690 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2691 s
.right
- s
.left
, ddsd
.dwWidth
);
2692 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2693 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2695 GetWindowRect(window
, &r
);
2696 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2697 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2698 r
.left
, r
.top
, r
.right
, r
.bottom
);
2700 expect_messages
= normal_messages
;
2704 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2705 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2707 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2708 expect_messages
= NULL
;
2709 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2711 GetWindowRect(window
, &r
);
2712 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2713 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2714 r
.left
, r
.top
, r
.right
, r
.bottom
);
2716 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2717 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2718 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2719 s
.right
- s
.left
, ddsd
.dwWidth
);
2720 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2721 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2722 IDirectDrawSurface_Release(primary
);
2724 memset(&ddsd
, 0, sizeof(ddsd
));
2725 ddsd
.dwSize
= sizeof(ddsd
);
2726 ddsd
.dwFlags
= DDSD_CAPS
;
2727 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2729 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2730 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2731 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2732 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2733 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2734 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2735 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2736 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2737 IDirectDrawSurface_Release(primary
);
2739 GetWindowRect(window
, &r
);
2740 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2741 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2742 r
.left
, r
.top
, r
.right
, r
.bottom
);
2744 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
2745 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2746 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2747 hr
= IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
2748 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2750 expect_messages
= exclusive_messages
;
2754 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2755 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2757 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2758 expect_messages
= NULL
;
2759 ok(screen_size
.cx
== fullscreen_rect
.right
&& screen_size
.cy
== fullscreen_rect
.bottom
,
2760 "Expected screen size %ux%u, got %ux%u.\n",
2761 fullscreen_rect
.right
, fullscreen_rect
.bottom
, screen_size
.cx
, screen_size
.cy
);
2763 GetWindowRect(window
, &r
);
2764 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2765 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2766 r
.left
, r
.top
, r
.right
, r
.bottom
);
2768 memset(&ddsd
, 0, sizeof(ddsd
));
2769 ddsd
.dwSize
= sizeof(ddsd
);
2770 ddsd
.dwFlags
= DDSD_CAPS
;
2771 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2773 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2774 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2775 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2776 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2777 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2778 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2779 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2780 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2781 IDirectDrawSurface_Release(primary
);
2783 /* The screen restore is a property of DDSCL_EXCLUSIVE */
2784 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2785 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2786 hr
= IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
2787 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2789 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2790 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2792 memset(&ddsd
, 0, sizeof(ddsd
));
2793 ddsd
.dwSize
= sizeof(ddsd
);
2794 ddsd
.dwFlags
= DDSD_CAPS
;
2795 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2797 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2798 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2799 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2800 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2801 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2802 s
.right
- s
.left
, ddsd
.dwWidth
);
2803 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2804 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2805 IDirectDrawSurface_Release(primary
);
2807 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2808 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2810 /* If the window is changed at the same time, messages are sent to the new window. */
2811 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2812 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2813 hr
= IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
2814 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2816 expect_messages
= exclusive_messages
;
2819 screen_size2
.cx
= 0;
2820 screen_size2
.cy
= 0;
2822 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
2823 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2825 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2826 expect_messages
= NULL
;
2827 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n",
2828 screen_size
.cx
, screen_size
.cy
);
2829 ok(screen_size2
.cx
== fullscreen_rect
.right
&& screen_size2
.cy
== fullscreen_rect
.bottom
,
2830 "Expected screen size 2 %ux%u, got %ux%u.\n",
2831 fullscreen_rect
.right
, fullscreen_rect
.bottom
, screen_size2
.cx
, screen_size2
.cy
);
2833 GetWindowRect(window
, &r
);
2834 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2835 s
.left
, s
.top
, s
.right
, s
.bottom
,
2836 r
.left
, r
.top
, r
.right
, r
.bottom
);
2837 GetWindowRect(window2
, &r
);
2838 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2839 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2840 r
.left
, r
.top
, r
.right
, r
.bottom
);
2842 memset(&ddsd
, 0, sizeof(ddsd
));
2843 ddsd
.dwSize
= sizeof(ddsd
);
2844 ddsd
.dwFlags
= DDSD_CAPS
;
2845 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2847 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2848 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2849 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2850 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2851 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2852 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2853 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2854 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2855 IDirectDrawSurface_Release(primary
);
2857 ref
= IDirectDraw2_Release(ddraw
);
2858 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2860 GetWindowRect(window
, &r
);
2861 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2862 s
.left
, s
.top
, s
.right
, s
.bottom
,
2863 r
.left
, r
.top
, r
.right
, r
.bottom
);
2866 expect_messages
= NULL
;
2867 DestroyWindow(window
);
2868 DestroyWindow(window2
);
2869 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2870 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
2873 static void test_coop_level_mode_set_multi(void)
2875 IDirectDraw2
*ddraw1
, *ddraw2
;
2876 UINT orig_w
, orig_h
, w
, h
;
2881 if (!(ddraw1
= create_ddraw()))
2883 skip("Failed to create a ddraw object, skipping test.\n");
2887 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2888 0, 0, 100, 100, 0, 0, 0, 0);
2890 orig_w
= GetSystemMetrics(SM_CXSCREEN
);
2891 orig_h
= GetSystemMetrics(SM_CYSCREEN
);
2893 /* With just a single ddraw object, the display mode is restored on
2895 hr
= IDirectDraw2_SetDisplayMode(ddraw1
, 800, 600, 32, 0, 0);
2896 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_NOEXCLUSIVEMODE
) /* NT4 testbot */,
2897 "SetDisplayMode failed, hr %#x.\n", hr
);
2898 if (hr
== DDERR_NOEXCLUSIVEMODE
)
2900 win_skip("Broken SetDisplayMode(), skipping test.\n");
2901 IDirectDraw2_Release(ddraw1
);
2902 DestroyWindow(window
);
2905 w
= GetSystemMetrics(SM_CXSCREEN
);
2906 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2907 h
= GetSystemMetrics(SM_CYSCREEN
);
2908 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2910 ref
= IDirectDraw2_Release(ddraw1
);
2911 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2912 w
= GetSystemMetrics(SM_CXSCREEN
);
2913 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2914 h
= GetSystemMetrics(SM_CYSCREEN
);
2915 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2917 /* When there are multiple ddraw objects, the display mode is restored to
2918 * the initial mode, before the first SetDisplayMode() call. */
2919 ddraw1
= create_ddraw();
2920 hr
= IDirectDraw2_SetDisplayMode(ddraw1
, 800, 600, 32, 0, 0);
2921 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2922 w
= GetSystemMetrics(SM_CXSCREEN
);
2923 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2924 h
= GetSystemMetrics(SM_CYSCREEN
);
2925 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2927 ddraw2
= create_ddraw();
2928 hr
= IDirectDraw2_SetDisplayMode(ddraw2
, 640, 480, 32, 0, 0);
2929 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2930 w
= GetSystemMetrics(SM_CXSCREEN
);
2931 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2932 h
= GetSystemMetrics(SM_CYSCREEN
);
2933 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2935 ref
= IDirectDraw2_Release(ddraw2
);
2936 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2937 w
= GetSystemMetrics(SM_CXSCREEN
);
2938 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2939 h
= GetSystemMetrics(SM_CYSCREEN
);
2940 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2942 ref
= IDirectDraw2_Release(ddraw1
);
2943 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2944 w
= GetSystemMetrics(SM_CXSCREEN
);
2945 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2946 h
= GetSystemMetrics(SM_CYSCREEN
);
2947 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2949 /* Regardless of release ordering. */
2950 ddraw1
= create_ddraw();
2951 hr
= IDirectDraw2_SetDisplayMode(ddraw1
, 800, 600, 32, 0, 0);
2952 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2953 w
= GetSystemMetrics(SM_CXSCREEN
);
2954 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2955 h
= GetSystemMetrics(SM_CYSCREEN
);
2956 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2958 ddraw2
= create_ddraw();
2959 hr
= IDirectDraw2_SetDisplayMode(ddraw2
, 640, 480, 32, 0, 0);
2960 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2961 w
= GetSystemMetrics(SM_CXSCREEN
);
2962 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2963 h
= GetSystemMetrics(SM_CYSCREEN
);
2964 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2966 ref
= IDirectDraw2_Release(ddraw1
);
2967 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2968 w
= GetSystemMetrics(SM_CXSCREEN
);
2969 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2970 h
= GetSystemMetrics(SM_CYSCREEN
);
2971 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2973 ref
= IDirectDraw2_Release(ddraw2
);
2974 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2975 w
= GetSystemMetrics(SM_CXSCREEN
);
2976 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2977 h
= GetSystemMetrics(SM_CYSCREEN
);
2978 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2980 /* But only for ddraw objects that called SetDisplayMode(). */
2981 ddraw1
= create_ddraw();
2982 ddraw2
= create_ddraw();
2983 hr
= IDirectDraw2_SetDisplayMode(ddraw2
, 640, 480, 32, 0, 0);
2984 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2985 w
= GetSystemMetrics(SM_CXSCREEN
);
2986 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2987 h
= GetSystemMetrics(SM_CYSCREEN
);
2988 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2990 ref
= IDirectDraw2_Release(ddraw1
);
2991 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2992 w
= GetSystemMetrics(SM_CXSCREEN
);
2993 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2994 h
= GetSystemMetrics(SM_CYSCREEN
);
2995 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2997 ref
= IDirectDraw2_Release(ddraw2
);
2998 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2999 w
= GetSystemMetrics(SM_CXSCREEN
);
3000 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
3001 h
= GetSystemMetrics(SM_CYSCREEN
);
3002 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
3004 /* If there's a ddraw object that's currently in exclusive mode, it blocks
3005 * restoring the display mode. */
3006 ddraw1
= create_ddraw();
3007 hr
= IDirectDraw2_SetDisplayMode(ddraw1
, 800, 600, 32, 0, 0);
3008 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
3009 w
= GetSystemMetrics(SM_CXSCREEN
);
3010 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3011 h
= GetSystemMetrics(SM_CYSCREEN
);
3012 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3014 ddraw2
= create_ddraw();
3015 hr
= IDirectDraw2_SetDisplayMode(ddraw2
, 640, 480, 32, 0, 0);
3016 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
3017 w
= GetSystemMetrics(SM_CXSCREEN
);
3018 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3019 h
= GetSystemMetrics(SM_CYSCREEN
);
3020 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3022 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3023 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3025 ref
= IDirectDraw2_Release(ddraw1
);
3026 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3027 w
= GetSystemMetrics(SM_CXSCREEN
);
3028 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3029 h
= GetSystemMetrics(SM_CYSCREEN
);
3030 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3032 ref
= IDirectDraw2_Release(ddraw2
);
3033 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3034 w
= GetSystemMetrics(SM_CXSCREEN
);
3035 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
3036 h
= GetSystemMetrics(SM_CYSCREEN
);
3037 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
3039 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
3040 ddraw1
= create_ddraw();
3041 hr
= IDirectDraw2_SetDisplayMode(ddraw1
, 800, 600, 32, 0, 0);
3042 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
3043 w
= GetSystemMetrics(SM_CXSCREEN
);
3044 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3045 h
= GetSystemMetrics(SM_CYSCREEN
);
3046 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3048 hr
= IDirectDraw2_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3049 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3051 ddraw2
= create_ddraw();
3052 hr
= IDirectDraw2_SetDisplayMode(ddraw2
, 640, 480, 32, 0, 0);
3053 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
3055 ref
= IDirectDraw2_Release(ddraw1
);
3056 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3057 w
= GetSystemMetrics(SM_CXSCREEN
);
3058 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
3059 h
= GetSystemMetrics(SM_CYSCREEN
);
3060 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
3062 ref
= IDirectDraw2_Release(ddraw2
);
3063 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3064 w
= GetSystemMetrics(SM_CXSCREEN
);
3065 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
3066 h
= GetSystemMetrics(SM_CYSCREEN
);
3067 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
3069 DestroyWindow(window
);
3072 static void test_initialize(void)
3074 IDirectDraw2
*ddraw
;
3077 if (!(ddraw
= create_ddraw()))
3079 skip("Failed to create a ddraw object, skipping test.\n");
3083 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
3084 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
3085 IDirectDraw2_Release(ddraw
);
3088 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw2
, (void **)&ddraw
);
3089 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr
);
3090 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
3091 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
3092 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
3093 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
3094 IDirectDraw2_Release(ddraw
);
3098 static void test_coop_level_surf_create(void)
3100 IDirectDrawSurface
*surface
;
3101 IDirectDraw2
*ddraw
;
3105 if (!(ddraw
= create_ddraw()))
3107 skip("Failed to create a ddraw object, skipping test.\n");
3111 memset(&ddsd
, 0, sizeof(ddsd
));
3112 ddsd
.dwSize
= sizeof(ddsd
);
3113 ddsd
.dwFlags
= DDSD_CAPS
;
3114 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3115 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3116 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
3118 IDirectDraw2_Release(ddraw
);
3121 static void test_coop_level_multi_window(void)
3123 HWND window1
, window2
;
3124 IDirectDraw2
*ddraw
;
3127 window1
= CreateWindowA("static", "ddraw_test1", WS_OVERLAPPEDWINDOW
,
3128 0, 0, 640, 480, 0, 0, 0, 0);
3129 window2
= CreateWindowA("static", "ddraw_test2", WS_OVERLAPPEDWINDOW
,
3130 0, 0, 640, 480, 0, 0, 0, 0);
3131 if (!(ddraw
= create_ddraw()))
3133 skip("Failed to create a ddraw object, skipping test.\n");
3134 DestroyWindow(window2
);
3135 DestroyWindow(window1
);
3139 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
3140 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3141 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3142 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3143 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
3144 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
3146 IDirectDraw2_Release(ddraw
);
3147 DestroyWindow(window2
);
3148 DestroyWindow(window1
);
3151 static void test_clear_rect_count(void)
3153 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3154 IDirect3DMaterial2
*white
, *red
, *green
, *blue
;
3155 IDirect3DViewport2
*viewport
;
3156 IDirect3DDevice2
*device
;
3157 IDirectDrawSurface
*rt
;
3158 IDirectDraw2
*ddraw
;
3163 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3164 0, 0, 640, 480, 0, 0, 0, 0);
3165 if (!(ddraw
= create_ddraw()))
3167 skip("Failed to create a ddraw object, skipping test.\n");
3168 DestroyWindow(window
);
3171 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3173 skip("Failed to create a 3D device, skipping test.\n");
3174 IDirectDraw2_Release(ddraw
);
3175 DestroyWindow(window
);
3179 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
3180 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3182 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
3183 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
3184 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
3185 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
3187 viewport
= create_viewport(device
, 0, 0, 640, 480);
3188 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
3189 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
3191 viewport_set_background(device
, viewport
, white
);
3192 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
3193 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3194 viewport_set_background(device
, viewport
, red
);
3195 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
3196 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3197 viewport_set_background(device
, viewport
, green
);
3198 hr
= IDirect3DViewport2_Clear(viewport
, 0, NULL
, D3DCLEAR_TARGET
);
3199 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3200 viewport_set_background(device
, viewport
, blue
);
3201 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
3202 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3204 color
= get_surface_color(rt
, 320, 240);
3205 ok(compare_color(color
, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", color
);
3207 IDirectDrawSurface_Release(rt
);
3208 destroy_viewport(device
, viewport
);
3209 destroy_material(white
);
3210 destroy_material(red
);
3211 destroy_material(green
);
3212 destroy_material(blue
);
3213 IDirect3DDevice2_Release(device
);
3214 IDirectDraw2_Release(ddraw
);
3215 DestroyWindow(window
);
3218 static BOOL
test_mode_restored(IDirectDraw2
*ddraw
, HWND window
)
3220 DDSURFACEDESC ddsd1
, ddsd2
;
3223 memset(&ddsd1
, 0, sizeof(ddsd1
));
3224 ddsd1
.dwSize
= sizeof(ddsd1
);
3225 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd1
);
3226 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
3228 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3229 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3230 hr
= IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
3231 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
3232 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3233 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3235 memset(&ddsd2
, 0, sizeof(ddsd2
));
3236 ddsd2
.dwSize
= sizeof(ddsd2
);
3237 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd2
);
3238 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
3239 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3240 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3242 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
3245 static void test_coop_level_versions(void)
3251 IDirectDrawSurface
*surface
;
3252 IDirectDraw2
*ddraw2
;
3255 window
= CreateWindowA("static", "ddraw_test1", WS_OVERLAPPEDWINDOW
,
3256 0, 0, 640, 480, 0, 0, 0, 0);
3258 if (!(ddraw2
= create_ddraw()))
3260 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
3261 restored
= test_mode_restored(ddraw2
, window
);
3262 ok(restored
, "Display mode not restored in new ddraw object\n");
3264 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
3265 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3266 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3268 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3269 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
3270 restored
= test_mode_restored(ddraw2
, window
);
3271 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
3273 /* A successful one does */
3274 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3275 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3276 restored
= test_mode_restored(ddraw2
, window
);
3277 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
3279 IDirectDraw_Release(ddraw
);
3280 IDirectDraw2_Release(ddraw2
);
3282 if (!(ddraw2
= create_ddraw()))
3284 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3285 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3287 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
3288 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3289 restored
= test_mode_restored(ddraw2
, window
);
3290 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
3292 IDirectDraw_Release(ddraw
);
3293 IDirectDraw2_Release(ddraw2
);
3295 /* A failing call does not restore the ddraw2+ behavior */
3296 if (!(ddraw2
= create_ddraw()))
3298 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3299 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3301 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3302 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3303 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3304 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
3305 restored
= test_mode_restored(ddraw2
, window
);
3306 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
3308 IDirectDraw_Release(ddraw
);
3309 IDirectDraw2_Release(ddraw2
);
3311 /* Neither does a sequence of successful calls with the new interface */
3312 if (!(ddraw2
= create_ddraw()))
3314 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3315 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3317 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3318 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3319 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3320 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3321 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
3322 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3324 restored
= test_mode_restored(ddraw2
, window
);
3325 ok(!restored
, "Display mode restored after ddraw1-ddraw2 SetCooperativeLevel() call sequence\n");
3326 IDirectDraw_Release(ddraw
);
3327 IDirectDraw2_Release(ddraw2
);
3329 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
3330 if (!(ddraw2
= create_ddraw()))
3332 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3333 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3335 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
3336 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3338 memset(&ddsd
, 0, sizeof(ddsd
));
3339 ddsd
.dwSize
= sizeof(ddsd
);
3340 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
3341 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
3342 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
3343 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3344 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#x.\n", hr
);
3345 IDirectDrawSurface_Release(surface
);
3346 restored
= test_mode_restored(ddraw2
, window
);
3347 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
3349 IDirectDraw_Release(ddraw
);
3350 IDirectDraw2_Release(ddraw2
);
3353 DestroyWindow(window
);
3356 static void test_lighting_interface_versions(void)
3358 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3359 IDirect3DMaterial2
*emissive
, *background
;
3360 IDirect3DViewport2
*viewport
;
3361 IDirect3DDevice2
*device
;
3362 IDirectDrawSurface
*rt
;
3363 IDirectDraw2
*ddraw
;
3368 D3DMATERIALHANDLE mat_handle
;
3369 D3DMATERIAL mat_desc
;
3373 static D3DVERTEX quad
[] =
3375 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3376 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3377 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3378 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3380 static D3DLVERTEX lquad
[] =
3382 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3383 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3384 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3385 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3387 static D3DTLVERTEX tlquad
[] =
3389 {{ 0.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3390 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3391 {{ 640.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3392 {{ 640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3396 D3DVERTEXTYPE vertextype
;
3398 DWORD d3drs_lighting
, d3drs_specular
;
3404 /* Lighting is enabled when D3DVT_VERTEX is used and D3DDP_DONOTLIGHT is not
3405 * set. D3DVT_VERTEX has diffuse = 0xffffffff and specular = 0x00000000, as
3406 * in later d3d versions */
3407 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, 0, 0x0000ff00},
3408 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, 0, 0x0000ff00},
3409 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3410 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3411 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, 0, 0x0000ff00},
3412 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, 0, 0x0000ff00},
3413 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3414 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3416 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, 0, 0x00ff0000},
3417 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, 0, 0x00ff0000},
3418 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
3419 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
3420 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, 0, 0x00ff8080},
3421 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, 0, 0x00ff8080},
3422 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
3423 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
3425 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, 0, 0x000000ff},
3426 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, 0, 0x000000ff},
3427 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
3428 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
3429 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, 0, 0x008080ff},
3430 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, 0, 0x008080ff},
3431 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
3432 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
3435 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3436 0, 0, 640, 480, 0, 0, 0, 0);
3437 if (!(ddraw
= create_ddraw()))
3439 skip("Failed to create a ddraw object, skipping test.\n");
3440 DestroyWindow(window
);
3443 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3445 skip("Failed to create a 3D device, skipping test.\n");
3446 IDirectDraw2_Release(ddraw
);
3447 DestroyWindow(window
);
3450 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
3451 ok(SUCCEEDED(hr
), "Failed to get IDirect3D2 interface, hr %#x.\n", hr
);
3453 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
3454 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3456 viewport
= create_viewport(device
, 0, 0, 640, 480);
3457 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
3458 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
3460 memset(&mat_desc
, 0, sizeof(mat_desc
));
3461 mat_desc
.dwSize
= sizeof(mat_desc
);
3462 U2(U3(mat_desc
).dcvEmissive
).g
= 1.0f
;
3463 hr
= IDirect3D2_CreateMaterial(d3d
, &emissive
, NULL
);
3464 ok(SUCCEEDED(hr
), "Failed to create material, hr %#x.\n", hr
);
3465 hr
= IDirect3DMaterial2_SetMaterial(emissive
, &mat_desc
);
3466 ok(SUCCEEDED(hr
), "Failed to set material, hr %#x.\n", hr
);
3467 hr
= IDirect3DMaterial2_GetHandle(emissive
, device
, &mat_handle
);
3468 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
3469 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
3470 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
3471 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
3472 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#x.\n", hr
);
3474 background
= create_diffuse_material(device
, 0.1f
, 0.1f
, 0.1f
, 0.1f
);
3475 hr
= IDirect3DMaterial2_GetHandle(background
, device
, &mat_handle
);
3476 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
3477 hr
= IDirect3DViewport2_SetBackground(viewport
, mat_handle
);
3478 ok(SUCCEEDED(hr
), "Failed to set background material, hr %#x.\n", hr
);
3480 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, &rs
);
3481 ok(SUCCEEDED(hr
), "Failed to get specularenable render state, hr %#x.\n", hr
);
3482 ok(rs
== TRUE
, "Initial D3DRENDERSTATE_SPECULARENABLE is %#x, expected TRUE.\n", rs
);
3484 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
3486 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
3487 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3489 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, tests
[i
].d3drs_lighting
);
3490 ok(SUCCEEDED(hr
), "Failed to set lighting render state, hr %#x.\n", hr
);
3491 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
,
3492 tests
[i
].d3drs_specular
);
3493 ok(SUCCEEDED(hr
), "Failed to set specularenable render state, hr %#x.\n", hr
);
3495 hr
= IDirect3DDevice2_BeginScene(device
);
3496 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
3497 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
3498 tests
[i
].vertextype
, tests
[i
].data
, 4, tests
[i
].draw_flags
| D3DDP_WAIT
);
3499 hr
= IDirect3DDevice2_EndScene(device
);
3500 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
3502 color
= get_surface_color(rt
, 320, 240);
3503 ok(compare_color(color
, tests
[i
].color
, 1),
3504 "Got unexpected color 0x%08x, expected 0x%08x, test %u.\n",
3505 color
, tests
[i
].color
, i
);
3508 IDirect3DMaterial2_Release(background
);
3509 IDirect3DMaterial2_Release(emissive
);
3510 IDirectDrawSurface_Release(rt
);
3511 IDirect3DDevice2_Release(device
);
3512 IDirect3D2_Release(d3d
);
3513 ref
= IDirectDraw2_Release(ddraw
);
3514 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
3515 DestroyWindow(window
);
3521 IDirectDraw2
*ddraw
;
3524 } activateapp_testdata
;
3526 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
3528 if (message
== WM_ACTIVATEAPP
)
3530 if (activateapp_testdata
.ddraw
)
3533 activateapp_testdata
.received
= FALSE
;
3534 hr
= IDirectDraw2_SetCooperativeLevel(activateapp_testdata
.ddraw
,
3535 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
3536 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#x.\n", hr
);
3537 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
3539 activateapp_testdata
.received
= TRUE
;
3542 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
3545 static void test_coop_level_activateapp(void)
3547 IDirectDraw2
*ddraw
;
3552 IDirectDrawSurface
*surface
;
3554 if (!(ddraw
= create_ddraw()))
3556 skip("Failed to create a ddraw object, skipping test.\n");
3560 wc
.lpfnWndProc
= activateapp_test_proc
;
3561 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
3562 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3564 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
3565 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
3567 /* Exclusive with window already active. */
3568 SetActiveWindow(window
);
3569 activateapp_testdata
.received
= FALSE
;
3570 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3571 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3572 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
3573 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3574 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3576 /* Exclusive with window not active. */
3577 SetActiveWindow(NULL
);
3578 activateapp_testdata
.received
= FALSE
;
3579 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3580 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3581 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3582 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3583 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3585 /* Normal with window not active, then exclusive with the same window. */
3586 SetActiveWindow(NULL
);
3587 activateapp_testdata
.received
= FALSE
;
3588 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3589 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3590 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
3591 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3592 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3593 /* Except in the first SetCooperativeLevel call, Windows XP randomly does not send
3594 * WM_ACTIVATEAPP. Windows 7 sends the message reliably. Mark the XP behavior broken. */
3595 ok(activateapp_testdata
.received
|| broken(!activateapp_testdata
.received
),
3596 "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3597 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3598 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3600 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
3601 SetActiveWindow(NULL
);
3602 activateapp_testdata
.received
= FALSE
;
3603 activateapp_testdata
.ddraw
= ddraw
;
3604 activateapp_testdata
.window
= window
;
3605 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
3606 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3607 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3608 ok(activateapp_testdata
.received
|| broken(!activateapp_testdata
.received
),
3609 "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3610 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3611 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3613 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
3614 * succeeding. Another switch to exclusive and back to normal is needed to release the
3615 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
3616 * WM_ACTIVATEAPP messages. */
3617 activateapp_testdata
.ddraw
= NULL
;
3618 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3619 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3620 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3621 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3623 /* Setting DDSCL_NORMAL with recursive invocation. */
3624 SetActiveWindow(NULL
);
3625 activateapp_testdata
.received
= FALSE
;
3626 activateapp_testdata
.ddraw
= ddraw
;
3627 activateapp_testdata
.window
= window
;
3628 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
3629 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3630 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3631 ok(activateapp_testdata
.received
|| broken(!activateapp_testdata
.received
),
3632 "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3634 /* DDraw is in exlusive mode now. */
3635 memset(&ddsd
, 0, sizeof(ddsd
));
3636 ddsd
.dwSize
= sizeof(ddsd
);
3637 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
3638 ddsd
.dwBackBufferCount
= 1;
3639 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
3640 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3641 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
3642 IDirectDrawSurface_Release(surface
);
3644 /* Recover again, just to be sure. */
3645 activateapp_testdata
.ddraw
= NULL
;
3646 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3647 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3648 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3649 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3651 DestroyWindow(window
);
3652 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3653 IDirectDraw2_Release(ddraw
);
3656 struct format_support_check
3658 const DDPIXELFORMAT
*format
;
3662 static HRESULT WINAPI
test_unsupported_formats_cb(DDSURFACEDESC
*desc
, void *ctx
)
3664 struct format_support_check
*format
= ctx
;
3666 if (!memcmp(format
->format
, &desc
->ddpfPixelFormat
, sizeof(*format
->format
)))
3668 format
->supported
= TRUE
;
3669 return DDENUMRET_CANCEL
;
3672 return DDENUMRET_OK
;
3675 static void test_unsupported_formats(void)
3678 BOOL expect_success
;
3680 IDirectDraw2
*ddraw
;
3681 IDirect3DDevice2
*device
;
3682 IDirectDrawSurface
*surface
;
3685 DWORD expected_caps
;
3696 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
3697 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
3703 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
3704 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3708 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
3710 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3711 0, 0, 640, 480, 0, 0, 0, 0);
3712 if (!(ddraw
= create_ddraw()))
3714 skip("Failed to create a ddraw object, skipping test.\n");
3715 DestroyWindow(window
);
3718 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3720 skip("Failed to create a 3D device, skipping test.\n");
3721 IDirectDraw2_Release(ddraw
);
3722 DestroyWindow(window
);
3726 for (i
= 0; i
< sizeof(formats
) / sizeof(*formats
); i
++)
3728 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
3729 hr
= IDirect3DDevice2_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
3730 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
3732 for (j
= 0; j
< sizeof(caps
) / sizeof(*caps
); j
++)
3734 memset(&ddsd
, 0, sizeof(ddsd
));
3735 ddsd
.dwSize
= sizeof(ddsd
);
3736 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
3737 ddsd
.ddpfPixelFormat
= formats
[i
].fmt
;
3740 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
3742 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
3743 expect_success
= FALSE
;
3745 expect_success
= TRUE
;
3747 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3748 ok(SUCCEEDED(hr
) == expect_success
,
3749 "Got unexpected hr %#x for format %s, caps %#x, expected %s.\n",
3750 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
3754 memset(&ddsd
, 0, sizeof(ddsd
));
3755 ddsd
.dwSize
= sizeof(ddsd
);
3756 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &ddsd
);
3757 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3759 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
3760 expected_caps
= DDSCAPS_VIDEOMEMORY
;
3761 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
3762 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
3763 else if (check
.supported
)
3764 expected_caps
= DDSCAPS_VIDEOMEMORY
;
3766 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
3768 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
3769 "Expected capability %#x, format %s, input cap %#x.\n",
3770 expected_caps
, formats
[i
].name
, caps
[j
]);
3772 IDirectDrawSurface_Release(surface
);
3776 IDirect3DDevice2_Release(device
);
3777 IDirectDraw2_Release(ddraw
);
3778 DestroyWindow(window
);
3781 static void test_rt_caps(void)
3783 PALETTEENTRY palette_entries
[256];
3784 IDirectDrawPalette
*palette
;
3785 IDirectDraw2
*ddraw
;
3793 static const DDPIXELFORMAT p8_fmt
=
3795 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
3796 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
3801 const DDPIXELFORMAT
*pf
;
3804 HRESULT create_device_hr
;
3806 HRESULT alternative_set_rt_hr
;
3807 BOOL create_may_fail
;
3813 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
3814 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3822 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
3823 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3831 DDSCAPS_OFFSCREENPLAIN
,
3832 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3840 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3841 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3842 D3DERR_SURFACENOTINVIDMEM
,
3849 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3850 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3858 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
3859 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3868 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3877 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3885 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3886 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3887 D3DERR_SURFACENOTINVIDMEM
,
3894 DDSCAPS_SYSTEMMEMORY
,
3895 DDSCAPS_SYSTEMMEMORY
,
3904 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3912 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
3914 DDERR_NOPALETTEATTACHED
,
3921 DDSCAPS_OFFSCREENPLAIN
,
3922 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3930 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3931 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3932 DDERR_NOPALETTEATTACHED
,
3939 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3940 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3948 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
3949 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
3951 DDERR_INVALIDPIXELFORMAT
,
3953 TRUE
/* AMD Evergreen */,
3957 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
3958 ~0U /* AMD Evergreen */,
3960 DDERR_INVALIDPIXELFORMAT
,
3967 ~0U /* AMD Evergreen */,
3975 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
3976 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
3978 DDERR_INVALIDPIXELFORMAT
,
3979 DDERR_INVALIDPIXELFORMAT
,
3980 TRUE
/* Nvidia Kepler */,
3984 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
3985 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
3989 TRUE
/* Nvidia Kepler */,
3993 if (!(ddraw
= create_ddraw()))
3995 skip("Failed to create a ddraw object, skipping test.\n");
3999 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4000 0, 0, 640, 480, 0, 0, 0, 0);
4001 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4002 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4004 if (FAILED(hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
4006 skip("D3D interface is not available, skipping test.\n");
4010 hr
= IDirect3D2_EnumDevices(d3d
, enum_z_fmt
, &z_depth
);
4011 if (FAILED(hr
) || !z_depth
)
4013 skip("No depth buffer formats available, skipping test.\n");
4014 IDirect3D2_Release(d3d
);
4018 memset(palette_entries
, 0, sizeof(palette_entries
));
4019 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
4020 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
4022 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
4024 IDirectDrawSurface
*surface
, *rt
, *expected_rt
, *tmp
;
4025 DDSURFACEDESC surface_desc
;
4026 IDirect3DDevice2
*device
;
4028 memset(&surface_desc
, 0, sizeof(surface_desc
));
4029 surface_desc
.dwSize
= sizeof(surface_desc
);
4030 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4031 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
4032 if (test_data
[i
].pf
)
4034 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
4035 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
4037 if (test_data
[i
].caps_in
& DDSCAPS_ZBUFFER
)
4039 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4040 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
4042 surface_desc
.dwWidth
= 640;
4043 surface_desc
.dwHeight
= 480;
4044 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4045 ok(SUCCEEDED(hr
) || broken(test_data
[i
].create_may_fail
),
4046 "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
4047 i
, test_data
[i
].caps_in
, hr
);
4051 memset(&surface_desc
, 0, sizeof(surface_desc
));
4052 surface_desc
.dwSize
= sizeof(surface_desc
);
4053 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
4054 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
4055 ok(test_data
[i
].caps_out
== ~0U || surface_desc
.ddsCaps
.dwCaps
== test_data
[i
].caps_out
,
4056 "Test %u: Got unexpected caps %#x, expected %#x.\n",
4057 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
4059 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
4060 ok(hr
== test_data
[i
].create_device_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n",
4061 i
, hr
, test_data
[i
].create_device_hr
);
4064 if (hr
== DDERR_NOPALETTEATTACHED
)
4066 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
4067 ok(SUCCEEDED(hr
), "Test %u: Failed to set palette, hr %#x.\n", i
, hr
);
4068 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
4069 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
4070 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
4072 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
4074 IDirectDrawSurface_Release(surface
);
4076 memset(&surface_desc
, 0, sizeof(surface_desc
));
4077 surface_desc
.dwSize
= sizeof(surface_desc
);
4078 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4079 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
4080 surface_desc
.dwWidth
= 640;
4081 surface_desc
.dwHeight
= 480;
4082 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4083 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface, hr %#x.\n", i
, hr
);
4085 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
4086 ok(SUCCEEDED(hr
), "Test %u: Failed to create device, hr %#x.\n", i
, hr
);
4089 memset(&surface_desc
, 0, sizeof(surface_desc
));
4090 surface_desc
.dwSize
= sizeof(surface_desc
);
4091 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4092 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
4093 if (test_data
[i
].pf
)
4095 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
4096 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
4098 if (test_data
[i
].caps_in
& DDSCAPS_ZBUFFER
)
4100 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4101 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
4103 surface_desc
.dwWidth
= 640;
4104 surface_desc
.dwHeight
= 480;
4105 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
4106 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
4107 i
, test_data
[i
].caps_in
, hr
);
4109 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
4110 ok(hr
== test_data
[i
].set_rt_hr
|| broken(hr
== test_data
[i
].alternative_set_rt_hr
),
4111 "Test %u: Got unexpected hr %#x, expected %#x.\n",
4112 i
, hr
, test_data
[i
].set_rt_hr
);
4113 if (SUCCEEDED(hr
) || hr
== DDERR_INVALIDPIXELFORMAT
)
4116 expected_rt
= surface
;
4118 /* It appears the surface is set as render target in this case, but no
4119 * reference is taken. */
4120 if (hr
== DDERR_INVALIDPIXELFORMAT
)
4122 refcount
= IDirectDrawSurface_AddRef(rt
);
4123 ok(refcount
== 2, "Test %u: Got unexpected refcount %u.\n", i
, refcount
);
4126 hr
= IDirect3DDevice2_GetRenderTarget(device
, &tmp
);
4127 ok(SUCCEEDED(hr
), "Test %u: Failed to get render target, hr %#x.\n", i
, hr
);
4128 ok(tmp
== expected_rt
, "Test %u: Got unexpected rt %p.\n", i
, tmp
);
4130 IDirectDrawSurface_Release(tmp
);
4131 IDirectDrawSurface_Release(rt
);
4132 refcount
= IDirect3DDevice2_Release(device
);
4133 ok(refcount
== 0, "Test %u: The device was not properly freed, refcount %u.\n", i
, refcount
);
4134 refcount
= IDirectDrawSurface_Release(surface
);
4135 ok(refcount
== 0, "Test %u: The surface was not properly freed, refcount %u.\n", i
, refcount
);
4138 IDirectDrawPalette_Release(palette
);
4139 IDirect3D2_Release(d3d
);
4142 refcount
= IDirectDraw2_Release(ddraw
);
4143 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4144 DestroyWindow(window
);
4147 static void test_primary_caps(void)
4149 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
4150 IDirectDrawSurface
*surface
;
4151 DDSURFACEDESC surface_desc
;
4152 IDirectDraw2
*ddraw
;
4162 DWORD back_buffer_count
;
4170 DDSCAPS_PRIMARYSURFACE
,
4173 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
4177 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
4184 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
4191 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
4198 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
4205 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
4212 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4219 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4226 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4228 DDERR_NOEXCLUSIVEMODE
,
4232 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4233 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4239 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4240 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4243 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
4246 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4247 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
4253 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4254 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
4261 if (!(ddraw
= create_ddraw()))
4263 skip("Failed to create a ddraw object, skipping test.\n");
4267 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4268 0, 0, 640, 480, 0, 0, 0, 0);
4270 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
4272 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
4273 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4275 memset(&surface_desc
, 0, sizeof(surface_desc
));
4276 surface_desc
.dwSize
= sizeof(surface_desc
);
4277 surface_desc
.dwFlags
= DDSD_CAPS
;
4278 if (test_data
[i
].back_buffer_count
!= ~0u)
4279 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
4280 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
4281 surface_desc
.dwBackBufferCount
= test_data
[i
].back_buffer_count
;
4282 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4283 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
4287 memset(&surface_desc
, 0, sizeof(surface_desc
));
4288 surface_desc
.dwSize
= sizeof(surface_desc
);
4289 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
4290 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
4291 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
4292 "Test %u: Got unexpected caps %#x, expected %#x.\n",
4293 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
4295 IDirectDrawSurface_Release(surface
);
4298 refcount
= IDirectDraw2_Release(ddraw
);
4299 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4300 DestroyWindow(window
);
4303 static void test_surface_lock(void)
4305 IDirectDraw2
*ddraw
;
4306 IDirect3D2
*d3d
= NULL
;
4307 IDirectDrawSurface
*surface
;
4322 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
4323 "videomemory offscreenplain"
4326 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4327 "systemmemory offscreenplain"
4330 DDSCAPS_PRIMARYSURFACE
,
4334 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
4335 "videomemory texture"
4338 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
4339 "systemmemory texture"
4342 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4351 if (!(ddraw
= create_ddraw()))
4353 skip("Failed to create a ddraw object, skipping test.\n");
4357 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4358 0, 0, 640, 480, 0, 0, 0, 0);
4359 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4360 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4362 if (FAILED(hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
4364 skip("D3D interface is not available, skipping test.\n");
4368 hr
= IDirect3D2_EnumDevices(d3d
, enum_z_fmt
, &z_depth
);
4369 if (FAILED(hr
) || !z_depth
)
4371 skip("No depth buffer formats available, skipping test.\n");
4375 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
4377 memset(&ddsd
, 0, sizeof(ddsd
)),
4378 ddsd
.dwSize
= sizeof(ddsd
);
4379 ddsd
.dwFlags
= DDSD_CAPS
;
4380 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
4382 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
4386 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
4388 ddsd
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4389 U2(ddsd
).dwZBufferBitDepth
= z_depth
;
4391 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
4393 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4394 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4396 memset(&ddsd
, 0, sizeof(ddsd
)),
4397 ddsd
.dwSize
= sizeof(ddsd
);
4398 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
4399 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4402 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4403 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4406 IDirectDrawSurface_Release(surface
);
4411 IDirect3D2_Release(d3d
);
4412 refcount
= IDirectDraw2_Release(ddraw
);
4413 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4414 DestroyWindow(window
);
4417 static void test_surface_discard(void)
4419 IDirectDraw2
*ddraw
;
4423 IDirectDrawSurface
*surface
, *primary
;
4432 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, TRUE
},
4433 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
4434 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, TRUE
},
4435 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
4439 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4440 0, 0, 640, 480, 0, 0, 0, 0);
4441 if (!(ddraw
= create_ddraw()))
4443 skip("Failed to create a ddraw object, skipping test.\n");
4444 DestroyWindow(window
);
4447 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4448 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4450 memset(&ddsd
, 0, sizeof(ddsd
));
4451 ddsd
.dwSize
= sizeof(ddsd
);
4452 ddsd
.dwFlags
= DDSD_CAPS
;
4453 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4454 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
4456 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
4460 memset(&ddsd
, 0, sizeof(ddsd
));
4461 ddsd
.dwSize
= sizeof(ddsd
);
4462 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4463 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
4466 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4469 skip("Failed to create surface, skipping.\n");
4473 memset(&ddsd
, 0, sizeof(ddsd
));
4474 ddsd
.dwSize
= sizeof(ddsd
);
4475 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
4476 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4477 addr
= ddsd
.lpSurface
;
4478 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4479 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4481 memset(&ddsd
, 0, sizeof(ddsd
));
4482 ddsd
.dwSize
= sizeof(ddsd
);
4483 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
4484 ok(SUCCEEDED(hr
) , "Failed to lock surface, hr %#x.\n", hr
);
4485 discarded
= ddsd
.lpSurface
!= addr
;
4486 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4487 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4489 hr
= IDirectDrawSurface_Blt(primary
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
4490 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
4492 memset(&ddsd
, 0, sizeof(ddsd
));
4493 ddsd
.dwSize
= sizeof(ddsd
);
4494 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
4495 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4496 discarded
|= ddsd
.lpSurface
!= addr
;
4497 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4498 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4500 IDirectDrawSurface_Release(surface
);
4502 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
4503 * AMD r500, evergreen). Windows XP, at least on AMD r200, never changes the pointer. */
4504 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
4507 IDirectDrawSurface_Release(primary
);
4508 IDirectDraw2_Release(ddraw
);
4509 DestroyWindow(window
);
4512 static void test_flip(void)
4514 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
4515 IDirectDrawSurface
*primary
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
4516 DDSCAPS caps
= {DDSCAPS_FLIP
};
4517 DDSURFACEDESC surface_desc
;
4518 BOOL sysmem_primary
;
4519 IDirectDraw2
*ddraw
;
4526 if (!(ddraw
= create_ddraw()))
4528 skip("Failed to create a ddraw object, skipping test.\n");
4532 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4533 0, 0, 640, 480, 0, 0, 0, 0);
4535 hr
= IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 32, 0, 0);
4536 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
4537 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4538 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4540 memset(&surface_desc
, 0, sizeof(surface_desc
));
4541 surface_desc
.dwSize
= sizeof(surface_desc
);
4542 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
4543 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
4544 surface_desc
.dwBackBufferCount
= 3;
4545 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
4546 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4548 memset(&surface_desc
, 0, sizeof(surface_desc
));
4549 surface_desc
.dwSize
= sizeof(surface_desc
);
4550 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
4551 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4552 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
)
4553 == (DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
),
4554 "Got unexpected caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
4555 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
4557 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &caps
, &backbuffer1
);
4558 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
4559 memset(&surface_desc
, 0, sizeof(surface_desc
));
4560 surface_desc
.dwSize
= sizeof(surface_desc
);
4561 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer1
, &surface_desc
);
4562 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4563 ok(!surface_desc
.dwBackBufferCount
, "Got unexpected back buffer count %u.\n", surface_desc
.dwBackBufferCount
);
4564 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == (DDSCAPS_FLIP
| DDSCAPS_COMPLEX
| DDSCAPS_BACKBUFFER
),
4565 "Got unexpected caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
4567 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
4568 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
4569 memset(&surface_desc
, 0, sizeof(surface_desc
));
4570 surface_desc
.dwSize
= sizeof(surface_desc
);
4571 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer2
, &surface_desc
);
4572 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4573 ok(!surface_desc
.dwBackBufferCount
, "Got unexpected back buffer count %u.\n", surface_desc
.dwBackBufferCount
);
4574 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == (DDSCAPS_FLIP
| DDSCAPS_COMPLEX
),
4575 "Got unexpected caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
4577 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
4578 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
4579 memset(&surface_desc
, 0, sizeof(surface_desc
));
4580 surface_desc
.dwSize
= sizeof(surface_desc
);
4581 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer3
, &surface_desc
);
4582 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4583 ok(!surface_desc
.dwBackBufferCount
, "Got unexpected back buffer count %u.\n", surface_desc
.dwBackBufferCount
);
4584 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == (DDSCAPS_FLIP
| DDSCAPS_COMPLEX
),
4585 "Got unexpected caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
4587 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
4588 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
4589 ok(surface
== primary
, "Got unexpected surface %p, expected %p.\n", surface
, primary
);
4590 IDirectDrawSurface_Release(surface
);
4592 memset(&surface_desc
, 0, sizeof(surface_desc
));
4593 surface_desc
.dwSize
= sizeof(surface_desc
);
4594 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4595 surface_desc
.ddsCaps
.dwCaps
= 0;
4596 surface_desc
.dwWidth
= 640;
4597 surface_desc
.dwHeight
= 480;
4598 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4599 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4600 hr
= IDirectDrawSurface_Flip(primary
, surface
, DDFLIP_WAIT
);
4601 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
4602 IDirectDrawSurface_Release(surface
);
4604 hr
= IDirectDrawSurface_Flip(primary
, primary
, DDFLIP_WAIT
);
4605 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
4606 hr
= IDirectDrawSurface_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
4607 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
4608 hr
= IDirectDrawSurface_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
4609 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
4610 hr
= IDirectDrawSurface_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
4611 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
4613 memset(&fx
, 0, sizeof(fx
));
4614 fx
.dwSize
= sizeof(fx
);
4615 U5(fx
).dwFillColor
= 0xffff0000;
4616 hr
= IDirectDrawSurface_Blt(backbuffer1
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4617 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4618 U5(fx
).dwFillColor
= 0xff00ff00;
4619 hr
= IDirectDrawSurface_Blt(backbuffer2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4620 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4621 U5(fx
).dwFillColor
= 0xff0000ff;
4622 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4623 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4625 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
4626 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
4627 color
= get_surface_color(backbuffer1
, 320, 240);
4628 /* The testbot seems to just copy the contents of one surface to all the
4629 * others, instead of properly flipping. */
4630 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
4631 "Got unexpected color 0x%08x.\n", color
);
4632 color
= get_surface_color(backbuffer2
, 320, 240);
4633 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
4634 U5(fx
).dwFillColor
= 0xffff0000;
4635 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4636 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4638 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
4639 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
4640 color
= get_surface_color(backbuffer1
, 320, 240);
4641 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
4642 "Got unexpected color 0x%08x.\n", color
);
4643 color
= get_surface_color(backbuffer2
, 320, 240);
4644 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
4645 U5(fx
).dwFillColor
= 0xff00ff00;
4646 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4647 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4649 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
4650 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
4651 color
= get_surface_color(backbuffer1
, 320, 240);
4652 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
4653 "Got unexpected color 0x%08x.\n", color
);
4654 color
= get_surface_color(backbuffer2
, 320, 240);
4655 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
4656 U5(fx
).dwFillColor
= 0xff0000ff;
4657 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4658 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4660 hr
= IDirectDrawSurface_Flip(primary
, backbuffer1
, DDFLIP_WAIT
);
4661 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
4662 color
= get_surface_color(backbuffer2
, 320, 240);
4663 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
4664 "Got unexpected color 0x%08x.\n", color
);
4665 color
= get_surface_color(backbuffer3
, 320, 240);
4666 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
4667 U5(fx
).dwFillColor
= 0xffff0000;
4668 hr
= IDirectDrawSurface_Blt(backbuffer1
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4669 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4671 hr
= IDirectDrawSurface_Flip(primary
, backbuffer2
, DDFLIP_WAIT
);
4672 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
4673 color
= get_surface_color(backbuffer1
, 320, 240);
4674 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
4675 color
= get_surface_color(backbuffer3
, 320, 240);
4676 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
4677 "Got unexpected color 0x%08x.\n", color
);
4678 U5(fx
).dwFillColor
= 0xff00ff00;
4679 hr
= IDirectDrawSurface_Blt(backbuffer2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4680 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4682 hr
= IDirectDrawSurface_Flip(primary
, backbuffer3
, DDFLIP_WAIT
);
4683 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
4684 color
= get_surface_color(backbuffer1
, 320, 240);
4685 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
4686 "Got unexpected color 0x%08x.\n", color
);
4687 color
= get_surface_color(backbuffer2
, 320, 240);
4688 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
4690 IDirectDrawSurface_Release(backbuffer3
);
4691 IDirectDrawSurface_Release(backbuffer2
);
4692 IDirectDrawSurface_Release(backbuffer1
);
4693 IDirectDrawSurface_Release(primary
);
4694 refcount
= IDirectDraw2_Release(ddraw
);
4695 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4696 DestroyWindow(window
);
4699 static void reset_ddsd(DDSURFACEDESC
*ddsd
)
4701 memset(ddsd
, 0, sizeof(*ddsd
));
4702 ddsd
->dwSize
= sizeof(*ddsd
);
4705 static void test_set_surface_desc(void)
4707 IDirectDraw2
*ddraw
;
4711 IDirectDrawSurface
*surface
;
4712 IDirectDrawSurface3
*surface3
;
4722 invalid_caps_tests
[] =
4724 {DDSCAPS_VIDEOMEMORY
, FALSE
, "videomemory plain"},
4725 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, TRUE
, "systemmemory texture"},
4726 {DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
, FALSE
, "systemmemory primary"},
4729 if (!(ddraw
= create_ddraw()))
4731 skip("Failed to create a ddraw object, skipping test.\n");
4735 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4736 0, 0, 640, 480, 0, 0, 0, 0);
4738 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4739 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4742 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
4745 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
4746 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4747 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
4748 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
4749 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
4750 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
4751 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
;
4753 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4754 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4756 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
4757 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
4758 IDirectDrawSurface_Release(surface
);
4761 ddsd
.dwFlags
= DDSD_LPSURFACE
;
4762 ddsd
.lpSurface
= data
;
4763 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4764 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4766 /* Redundantly setting the same lpSurface is not an error. */
4767 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4768 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4769 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
4770 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4771 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
4772 ok(ddsd
.lpSurface
== NULL
, "lpSurface is %p, expected NULL.\n", ddsd
.lpSurface
);
4774 hr
= IDirectDrawSurface3_Lock(surface3
, NULL
, &ddsd
, 0, NULL
);
4775 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4776 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
4777 ok(ddsd
.lpSurface
== data
, "lpSurface is %p, expected %p.\n", data
, data
);
4778 hr
= IDirectDrawSurface3_Unlock(surface3
, NULL
);
4779 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4782 ddsd
.dwFlags
= DDSD_LPSURFACE
;
4783 ddsd
.lpSurface
= data
;
4784 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 1);
4785 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with flags=1 returned %#x.\n", hr
);
4787 ddsd
.lpSurface
= NULL
;
4788 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4789 ok(hr
== DDERR_INVALIDPARAMS
, "Setting lpSurface=NULL returned %#x.\n", hr
);
4791 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, NULL
, 0);
4792 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with NULL desc returned %#x.\n", hr
);
4794 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
4795 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4796 ok(ddsd
.ddsCaps
.dwCaps
== DDSCAPS_SYSTEMMEMORY
, "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
4798 /* Setting the caps is an error. This also means the original description cannot be reapplied. */
4799 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4800 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the original desc returned %#x.\n", hr
);
4802 ddsd
.dwFlags
= DDSD_CAPS
;
4803 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4804 ok(hr
== DDERR_INVALIDPARAMS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
4806 /* dwCaps = 0 is allowed, but ignored. */
4807 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_LPSURFACE
;
4808 ddsd
.lpSurface
= data
;
4809 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4810 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
4811 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
;
4812 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4813 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
4814 ddsd
.ddsCaps
.dwCaps
= 0;
4815 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4816 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4818 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
4819 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4820 ok(ddsd
.ddsCaps
.dwCaps
== DDSCAPS_SYSTEMMEMORY
, "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
4822 /* Setting the height is allowed, but it cannot be set to 0, and only if LPSURFACE is set too. */
4824 ddsd
.dwFlags
= DDSD_HEIGHT
;
4826 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4827 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height without lpSurface returned %#x.\n", hr
);
4829 ddsd
.lpSurface
= data
;
4830 ddsd
.dwFlags
= DDSD_HEIGHT
| DDSD_LPSURFACE
;
4831 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4832 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4835 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4836 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height=0 returned %#x.\n", hr
);
4839 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
4840 ok(SUCCEEDED(hr
), "GetSurfaceDesc failed, hr %#x.\n", hr
);
4841 ok(ddsd
.dwWidth
== 8, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
4842 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
4844 /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0. */
4846 ddsd
.dwFlags
= DDSD_PITCH
;
4847 U1(ddsd
).lPitch
= 8 * 4;
4848 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4849 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch without lpSurface or width returned %#x.\n", hr
);
4851 ddsd
.dwFlags
= DDSD_WIDTH
;
4853 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4854 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width without lpSurface or pitch returned %#x.\n", hr
);
4856 ddsd
.dwFlags
= DDSD_PITCH
| DDSD_LPSURFACE
;
4857 ddsd
.lpSurface
= data
;
4858 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4859 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch and lpSurface without width returned %#x.\n", hr
);
4861 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_LPSURFACE
;
4862 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4863 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width and lpSurface without pitch returned %#x.\n", hr
);
4865 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
4866 U1(ddsd
).lPitch
= 16 * 4;
4868 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4869 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4872 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
4873 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4874 ok(ddsd
.dwWidth
== 16, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
4875 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
4876 ok(U1(ddsd
).lPitch
== 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %u.\n", U1(ddsd
).lPitch
);
4878 /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise.
4880 * VMware rejects those calls, but all real drivers accept it. Mark the VMware behavior broken. */
4881 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
4882 U1(ddsd
).lPitch
= 4 * 4;
4883 ddsd
.lpSurface
= data
;
4884 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4885 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
4887 U1(ddsd
).lPitch
= 4;
4888 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4889 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
4891 U1(ddsd
).lPitch
= 16 * 4 + 1;
4892 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4893 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
4895 U1(ddsd
).lPitch
= 16 * 4 + 3;
4896 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4897 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
4899 U1(ddsd
).lPitch
= -4;
4900 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4901 ok(hr
== DDERR_INVALIDPARAMS
, "Setting negative pitch returned %#x.\n", hr
);
4903 U1(ddsd
).lPitch
= 16 * 4;
4904 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4905 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4908 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
4909 U1(ddsd
).lPitch
= 0;
4911 ddsd
.lpSurface
= data
;
4912 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4913 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero pitch returned %#x.\n", hr
);
4915 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
4916 U1(ddsd
).lPitch
= 16 * 4;
4918 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4919 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero width returned %#x.\n", hr
);
4921 /* Setting the pixelformat without LPSURFACE is an error, but with LPSURFACE it works. */
4922 ddsd
.dwFlags
= DDSD_PIXELFORMAT
;
4923 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
4924 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4925 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
4926 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
4927 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
4928 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
4929 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4930 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the pixel format returned %#x.\n", hr
);
4932 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
4933 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4934 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4936 /* Can't set color keys. */
4938 ddsd
.dwFlags
= DDSD_CKSRCBLT
;
4939 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff0000;
4940 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff0000;
4941 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4942 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
4944 ddsd
.dwFlags
= DDSD_CKSRCBLT
| DDSD_LPSURFACE
;
4945 ddsd
.lpSurface
= data
;
4946 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4947 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
4949 IDirectDrawSurface3_Release(surface3
);
4951 /* SetSurfaceDesc needs systemmemory surfaces.
4953 * As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing DDSD_LINEARSIZE is moot. */
4954 for (i
= 0; i
< sizeof(invalid_caps_tests
) / sizeof(*invalid_caps_tests
); i
++)
4957 ddsd
.dwFlags
= DDSD_CAPS
;
4958 ddsd
.ddsCaps
.dwCaps
= invalid_caps_tests
[i
].caps
;
4959 if (!(invalid_caps_tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
4961 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
4964 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
4965 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4966 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
4967 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
4968 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
4969 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
4972 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4973 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
, "Failed to create surface, hr %#x.\n", hr
);
4976 skip("Cannot create a %s surface, skipping vidmem SetSurfaceDesc test.\n",
4977 invalid_caps_tests
[i
].name
);
4980 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
4981 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
4982 IDirectDrawSurface_Release(surface
);
4985 ddsd
.dwFlags
= DDSD_LPSURFACE
;
4986 ddsd
.lpSurface
= data
;
4987 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4988 if (invalid_caps_tests
[i
].supported
)
4990 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4994 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
4995 invalid_caps_tests
[i
].name
, hr
);
4997 /* Check priority of error conditions. */
4998 ddsd
.dwFlags
= DDSD_WIDTH
;
4999 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5000 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
5001 invalid_caps_tests
[i
].name
, hr
);
5004 IDirectDrawSurface3_Release(surface3
);
5008 ref
= IDirectDraw2_Release(ddraw
);
5009 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
5010 DestroyWindow(window
);
5013 static void test_user_memory_getdc(void)
5015 IDirectDraw2
*ddraw
;
5019 IDirectDrawSurface
*surface
;
5020 IDirectDrawSurface3
*surface3
;
5026 if (!(ddraw
= create_ddraw()))
5028 skip("Failed to create a ddraw object, skipping test.\n");
5032 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5033 0, 0, 640, 480, 0, 0, 0, 0);
5035 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5036 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5039 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
5042 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5043 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5044 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5045 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5046 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5047 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5048 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
;
5049 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5050 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5052 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
5053 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
5054 IDirectDrawSurface_Release(surface
);
5056 memset(data
, 0xaa, sizeof(data
));
5058 ddsd
.dwFlags
= DDSD_LPSURFACE
;
5059 ddsd
.lpSurface
= data
;
5060 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5061 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5063 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
5064 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
5065 BitBlt(dc
, 0, 0, 16, 8, NULL
, 0, 0, WHITENESS
);
5066 BitBlt(dc
, 0, 8, 16, 8, NULL
, 0, 0, BLACKNESS
);
5067 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
5068 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
5070 ok(data
[0][0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data
[0][0]);
5071 ok(data
[15][15] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data
[15][15]);
5073 ddsd
.dwFlags
= DDSD_LPSURFACE
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
;
5074 ddsd
.lpSurface
= data
;
5077 U1(ddsd
).lPitch
= sizeof(*data
);
5078 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5079 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5081 memset(data
, 0xaa, sizeof(data
));
5082 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
5083 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
5084 BitBlt(dc
, 0, 0, 4, 8, NULL
, 0, 0, BLACKNESS
);
5085 BitBlt(dc
, 1, 1, 2, 2, NULL
, 0, 0, WHITENESS
);
5086 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
5087 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
5089 for (y
= 0; y
< 4; y
++)
5091 for (x
= 0; x
< 4; x
++)
5093 if ((x
== 1 || x
== 2) && (y
== 1 || y
== 2))
5094 ok(data
[y
][x
] == 0xffffffff, "Expected color 0xffffffff on position %ux%u, got %#x.\n",
5097 ok(data
[y
][x
] == 0x00000000, "Expected color 0xaaaaaaaa on position %ux%u, got %#x.\n",
5101 ok(data
[0][5] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 5x0, got %#x.\n",
5103 ok(data
[7][3] == 0x00000000, "Expected color 0x00000000 on position 3x7, got %#x.\n",
5105 ok(data
[7][4] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 4x7, got %#x.\n",
5107 ok(data
[8][0] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 0x8, got %#x.\n",
5110 IDirectDrawSurface3_Release(surface3
);
5111 ref
= IDirectDraw2_Release(ddraw
);
5112 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
5113 DestroyWindow(window
);
5116 static void test_sysmem_overlay(void)
5118 IDirectDraw2
*ddraw
;
5122 IDirectDrawSurface
*surface
;
5125 if (!(ddraw
= create_ddraw()))
5127 skip("Failed to create a ddraw object, skipping test.\n");
5131 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5132 0, 0, 640, 480, 0, 0, 0, 0);
5134 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5135 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5138 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
5141 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
5142 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5143 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5144 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5145 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5146 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5147 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5148 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5149 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#x.\n", hr
);
5151 ref
= IDirectDraw2_Release(ddraw
);
5152 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
5153 DestroyWindow(window
);
5156 static void test_primary_palette(void)
5158 DDSCAPS surface_caps
= {DDSCAPS_FLIP
};
5159 IDirectDrawSurface
*primary
, *backbuffer
;
5160 PALETTEENTRY palette_entries
[256];
5161 IDirectDrawPalette
*palette
, *tmp
;
5162 DDSURFACEDESC surface_desc
;
5163 IDirectDraw2
*ddraw
;
5169 if (!(ddraw
= create_ddraw()))
5171 skip("Failed to create a ddraw object, skipping test.\n");
5175 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5176 0, 0, 640, 480, 0, 0, 0, 0);
5177 hr
= IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0);
5178 if (hr
== E_NOTIMPL
)
5180 win_skip("changing display mode is not supported (8bpp)\n");
5181 IDirectDraw2_Release(ddraw
);
5182 DestroyWindow(window
);
5185 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
5186 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5187 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5189 memset(&surface_desc
, 0, sizeof(surface_desc
));
5190 surface_desc
.dwSize
= sizeof(surface_desc
);
5191 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
5192 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
5193 surface_desc
.dwBackBufferCount
= 1;
5194 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
5195 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5196 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
5197 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
5199 memset(palette_entries
, 0, sizeof(palette_entries
));
5200 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
5201 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
5202 refcount
= get_refcount((IUnknown
*)palette
);
5203 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5205 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5206 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
5207 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
5209 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
5210 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5211 refcount
= get_refcount((IUnknown
*)palette
);
5212 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5214 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5215 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
5216 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
5217 "Got unexpected palette caps %#x.\n", palette_caps
);
5219 hr
= IDirectDrawSurface_SetPalette(primary
, NULL
);
5220 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5221 refcount
= get_refcount((IUnknown
*)palette
);
5222 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5224 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5225 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
5226 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
5228 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
5229 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5230 refcount
= get_refcount((IUnknown
*)palette
);
5231 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5233 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
5234 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
5235 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
5236 IDirectDrawPalette_Release(tmp
);
5237 hr
= IDirectDrawSurface_GetPalette(backbuffer
, &tmp
);
5238 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
5240 refcount
= IDirectDrawPalette_Release(palette
);
5241 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5242 refcount
= IDirectDrawPalette_Release(palette
);
5243 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5245 /* Note that this only seems to work when the palette is attached to the
5246 * primary surface. When attached to a regular surface, attempting to get
5247 * the palette here will cause an access violation. */
5248 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
5249 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
5251 refcount
= IDirectDrawSurface_Release(backbuffer
);
5252 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5253 refcount
= IDirectDrawSurface_Release(primary
);
5254 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5255 refcount
= IDirectDraw2_Release(ddraw
);
5256 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5257 DestroyWindow(window
);
5260 static HRESULT WINAPI
surface_counter(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
5262 UINT
*surface_count
= context
;
5265 IDirectDrawSurface_Release(surface
);
5267 return DDENUMRET_OK
;
5270 static void test_surface_attachment(void)
5272 IDirectDrawSurface
*surface1
, *surface2
, *surface3
, *surface4
;
5273 DDSCAPS caps
= {DDSCAPS_TEXTURE
};
5274 DDSURFACEDESC surface_desc
;
5275 IDirectDraw2
*ddraw
;
5281 if (!(ddraw
= create_ddraw()))
5283 skip("Failed to create a ddraw object, skipping test.\n");
5287 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5288 0, 0, 640, 480, 0, 0, 0, 0);
5289 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5290 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5292 memset(&surface_desc
, 0, sizeof(surface_desc
));
5293 surface_desc
.dwSize
= sizeof(surface_desc
);
5294 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
5295 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
5296 U2(surface_desc
).dwMipMapCount
= 3;
5297 surface_desc
.dwWidth
= 128;
5298 surface_desc
.dwHeight
= 128;
5299 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5300 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5302 hr
= IDirectDrawSurface_GetAttachedSurface(surface1
, &caps
, &surface2
);
5303 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
5304 hr
= IDirectDrawSurface_GetAttachedSurface(surface2
, &caps
, &surface3
);
5305 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
5306 hr
= IDirectDrawSurface_GetAttachedSurface(surface3
, &caps
, &surface4
);
5307 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
5310 IDirectDrawSurface_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
5311 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
5313 IDirectDrawSurface_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
5314 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
5316 IDirectDrawSurface_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
5317 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
5319 memset(&surface_desc
, 0, sizeof(surface_desc
));
5320 surface_desc
.dwSize
= sizeof(surface_desc
);
5321 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5322 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5323 surface_desc
.dwWidth
= 16;
5324 surface_desc
.dwHeight
= 16;
5325 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5326 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5328 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
5329 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5330 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5331 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5332 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
5333 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5334 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
5335 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5336 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
5337 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5338 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
5339 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5341 IDirectDrawSurface_Release(surface4
);
5343 memset(&surface_desc
, 0, sizeof(surface_desc
));
5344 surface_desc
.dwSize
= sizeof(surface_desc
);
5345 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5346 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5347 surface_desc
.dwWidth
= 16;
5348 surface_desc
.dwHeight
= 16;
5349 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5350 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5352 if (SUCCEEDED(hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
)))
5354 skip("Running on refrast, skipping some tests.\n");
5355 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface4
);
5356 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5360 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5361 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5362 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5363 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
5364 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5365 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
5366 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5367 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
5368 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5369 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
5370 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5373 IDirectDrawSurface_Release(surface4
);
5374 IDirectDrawSurface_Release(surface3
);
5375 IDirectDrawSurface_Release(surface2
);
5376 IDirectDrawSurface_Release(surface1
);
5378 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5379 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5381 /* Try a single primary and two offscreen plain surfaces. */
5382 memset(&surface_desc
, 0, sizeof(surface_desc
));
5383 surface_desc
.dwSize
= sizeof(surface_desc
);
5384 surface_desc
.dwFlags
= DDSD_CAPS
;
5385 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
5386 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5387 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5389 memset(&surface_desc
, 0, sizeof(surface_desc
));
5390 surface_desc
.dwSize
= sizeof(surface_desc
);
5391 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5392 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5393 surface_desc
.dwWidth
= GetSystemMetrics(SM_CXSCREEN
);
5394 surface_desc
.dwHeight
= GetSystemMetrics(SM_CYSCREEN
);
5395 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
5396 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5398 memset(&surface_desc
, 0, sizeof(surface_desc
));
5399 surface_desc
.dwSize
= sizeof(surface_desc
);
5400 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5401 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5402 surface_desc
.dwWidth
= GetSystemMetrics(SM_CXSCREEN
);
5403 surface_desc
.dwHeight
= GetSystemMetrics(SM_CYSCREEN
);
5404 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
5405 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5407 /* This one has a different size. */
5408 memset(&surface_desc
, 0, sizeof(surface_desc
));
5409 surface_desc
.dwSize
= sizeof(surface_desc
);
5410 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5411 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5412 surface_desc
.dwWidth
= 128;
5413 surface_desc
.dwHeight
= 128;
5414 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5415 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5417 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5418 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5419 /* Try the reverse without detaching first. */
5420 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
5421 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
5422 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5423 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5425 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
5426 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5427 /* Try to detach reversed. */
5428 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5429 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5430 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface1
);
5431 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5433 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface3
);
5434 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5435 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface3
);
5436 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5438 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
5439 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5440 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5441 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5443 IDirectDrawSurface_Release(surface4
);
5444 IDirectDrawSurface_Release(surface3
);
5445 IDirectDrawSurface_Release(surface2
);
5446 IDirectDrawSurface_Release(surface1
);
5448 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
5449 memset(&surface_desc
, 0, sizeof(surface_desc
));
5450 surface_desc
.dwSize
= sizeof(surface_desc
);
5451 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5452 surface_desc
.dwWidth
= 64;
5453 surface_desc
.dwHeight
= 64;
5454 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
5455 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5456 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
5457 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
5458 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
5459 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
5460 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
5461 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5462 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5463 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
5464 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5466 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
5467 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
5468 U1(surface_desc
.ddpfPixelFormat
).dwZBufferBitDepth
= 16;
5469 U3(surface_desc
.ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
5470 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
5471 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5473 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5474 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5475 refcount
= get_refcount((IUnknown
*)surface2
);
5476 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5477 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5478 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
5480 /* Attaching while already attached to other surface. */
5481 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface2
);
5482 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5483 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface3
, 0, surface2
);
5484 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5485 IDirectDrawSurface_Release(surface3
);
5487 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5488 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5489 refcount
= get_refcount((IUnknown
*)surface2
);
5490 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5492 /* Automatic detachment on release. */
5493 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5494 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5495 refcount
= get_refcount((IUnknown
*)surface2
);
5496 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5497 refcount
= IDirectDrawSurface_Release(surface1
);
5498 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5499 refcount
= IDirectDrawSurface_Release(surface2
);
5500 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5501 refcount
= IDirectDraw2_Release(ddraw
);
5502 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5503 DestroyWindow(window
);
5506 static void test_pixel_format(void)
5508 HWND window
, window2
= NULL
;
5509 HDC hdc
, hdc2
= NULL
;
5511 int format
, test_format
;
5512 PIXELFORMATDESCRIPTOR pfd
;
5513 IDirectDraw2
*ddraw
= NULL
;
5514 IDirectDrawClipper
*clipper
= NULL
;
5516 IDirectDrawSurface
*primary
= NULL
;
5520 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
5521 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
5524 skip("Failed to create window\n");
5528 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
5529 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
5531 hdc
= GetDC(window
);
5534 skip("Failed to get DC\n");
5539 hdc2
= GetDC(window2
);
5541 gl
= LoadLibraryA("opengl32.dll");
5542 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
5544 format
= GetPixelFormat(hdc
);
5545 ok(format
== 0, "new window has pixel format %d\n", format
);
5547 ZeroMemory(&pfd
, sizeof(pfd
));
5548 pfd
.nSize
= sizeof(pfd
);
5550 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
5551 pfd
.iPixelType
= PFD_TYPE_RGBA
;
5552 pfd
.iLayerType
= PFD_MAIN_PLANE
;
5553 format
= ChoosePixelFormat(hdc
, &pfd
);
5556 skip("no pixel format available\n");
5560 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
5562 skip("failed to set pixel format\n");
5566 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
5568 skip("failed to set pixel format on second window\n");
5571 ReleaseDC(window2
, hdc2
);
5576 ddraw
= create_ddraw();
5579 skip("Failed to create ddraw object\n");
5583 test_format
= GetPixelFormat(hdc
);
5584 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5586 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5589 skip("Failed to set cooperative level, hr %#x.\n", hr
);
5593 test_format
= GetPixelFormat(hdc
);
5594 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5598 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
5599 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
5600 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
5601 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
5603 test_format
= GetPixelFormat(hdc
);
5604 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5606 test_format
= GetPixelFormat(hdc2
);
5607 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5610 memset(&ddsd
, 0, sizeof(ddsd
));
5611 ddsd
.dwSize
= sizeof(ddsd
);
5612 ddsd
.dwFlags
= DDSD_CAPS
;
5613 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
5615 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
5616 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
5618 test_format
= GetPixelFormat(hdc
);
5619 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5623 test_format
= GetPixelFormat(hdc2
);
5624 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5629 hr
= IDirectDrawSurface2_SetClipper(primary
, clipper
);
5630 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
5632 test_format
= GetPixelFormat(hdc
);
5633 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5635 test_format
= GetPixelFormat(hdc2
);
5636 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5639 memset(&fx
, 0, sizeof(fx
));
5640 fx
.dwSize
= sizeof(fx
);
5641 hr
= IDirectDrawSurface2_Blt(primary
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
5642 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
5644 test_format
= GetPixelFormat(hdc
);
5645 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5649 test_format
= GetPixelFormat(hdc2
);
5650 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5654 if (primary
) IDirectDrawSurface2_Release(primary
);
5655 if (clipper
) IDirectDrawClipper_Release(clipper
);
5656 if (ddraw
) IDirectDraw2_Release(ddraw
);
5657 if (gl
) FreeLibrary(gl
);
5658 if (hdc
) ReleaseDC(window
, hdc
);
5659 if (hdc2
) ReleaseDC(window2
, hdc2
);
5660 if (window
) DestroyWindow(window
);
5661 if (window2
) DestroyWindow(window2
);
5666 test_coop_level_create_device_window();
5668 test_coop_level_d3d_state();
5669 test_surface_interface_mismatch();
5670 test_coop_level_threaded();
5672 test_texture_load_ckey();
5681 test_window_style();
5682 test_redundant_mode_set();
5683 test_coop_level_mode_set();
5684 test_coop_level_mode_set_multi();
5686 test_coop_level_surf_create();
5687 test_coop_level_multi_window();
5688 test_clear_rect_count();
5689 test_coop_level_versions();
5690 test_lighting_interface_versions();
5691 test_coop_level_activateapp();
5692 test_unsupported_formats();
5694 test_primary_caps();
5695 test_surface_lock();
5696 test_surface_discard();
5698 test_set_surface_desc();
5699 test_user_memory_getdc();
5700 test_sysmem_overlay();
5701 test_primary_palette();
5702 test_surface_attachment();
5703 test_pixel_format();