2 * Copyright 2011-2012 Henri Verbeet for CodeWeavers
3 * Copyright 2012-2013 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 D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
101 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
102 DDSURFACEDESC surface_desc
;
106 memset(&surface_desc
, 0, sizeof(surface_desc
));
107 surface_desc
.dwSize
= sizeof(surface_desc
);
109 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
110 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
114 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
116 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
117 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
122 static void emit_process_vertices(void **ptr
, WORD base_idx
, DWORD vertex_count
)
124 D3DINSTRUCTION
*inst
= *ptr
;
125 D3DPROCESSVERTICES
*pv
= (D3DPROCESSVERTICES
*)(inst
+ 1);
127 inst
->bOpcode
= D3DOP_PROCESSVERTICES
;
128 inst
->bSize
= sizeof(*pv
);
131 pv
->dwFlags
= D3DPROCESSVERTICES_COPY
;
132 pv
->wStart
= base_idx
;
134 pv
->dwCount
= vertex_count
;
140 static void emit_set_rs(void **ptr
, D3DRENDERSTATETYPE state
, DWORD value
)
142 D3DINSTRUCTION
*inst
= *ptr
;
143 D3DSTATE
*rs
= (D3DSTATE
*)(inst
+ 1);
145 inst
->bOpcode
= D3DOP_STATERENDER
;
146 inst
->bSize
= sizeof(*rs
);
149 U1(*rs
).drstRenderStateType
= state
;
150 U2(*rs
).dwArg
[0] = value
;
155 static void emit_tquad(void **ptr
, WORD base_idx
)
157 D3DINSTRUCTION
*inst
= *ptr
;
158 D3DTRIANGLE
*tri
= (D3DTRIANGLE
*)(inst
+ 1);
160 inst
->bOpcode
= D3DOP_TRIANGLE
;
161 inst
->bSize
= sizeof(*tri
);
164 U1(*tri
).v1
= base_idx
;
165 U2(*tri
).v2
= base_idx
+ 1;
166 U3(*tri
).v3
= base_idx
+ 2;
167 tri
->wFlags
= D3DTRIFLAG_START
;
170 U1(*tri
).v1
= base_idx
+ 2;
171 U2(*tri
).v2
= base_idx
+ 1;
172 U3(*tri
).v3
= base_idx
+ 3;
173 tri
->wFlags
= D3DTRIFLAG_ODD
;
179 static void emit_end(void **ptr
)
181 D3DINSTRUCTION
*inst
= *ptr
;
183 inst
->bOpcode
= D3DOP_EXIT
;
190 static void set_execute_data(IDirect3DExecuteBuffer
*execute_buffer
, UINT vertex_count
, UINT offset
, UINT len
)
192 D3DEXECUTEDATA exec_data
;
195 memset(&exec_data
, 0, sizeof(exec_data
));
196 exec_data
.dwSize
= sizeof(exec_data
);
197 exec_data
.dwVertexCount
= vertex_count
;
198 exec_data
.dwInstructionOffset
= offset
;
199 exec_data
.dwInstructionLength
= len
;
200 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
201 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#x.\n", hr
);
204 static HRESULT CALLBACK
enum_z_fmt(GUID
*guid
, char *description
, char *name
,
205 D3DDEVICEDESC
*hal_desc
, D3DDEVICEDESC
*hel_desc
, void *ctx
)
207 DWORD
*z_depth
= ctx
;
209 if (!IsEqualGUID(&IID_IDirect3DHALDevice
, guid
))
210 return D3DENUMRET_OK
;
212 if (hal_desc
->dwDeviceZBufferBitDepth
& DDBD_32
)
214 else if (hal_desc
->dwDeviceZBufferBitDepth
& DDBD_24
)
216 else if (hal_desc
->dwDeviceZBufferBitDepth
& DDBD_16
)
222 static IDirectDraw
*create_ddraw(void)
226 if (FAILED(DirectDrawCreate(NULL
, &ddraw
, NULL
)))
232 static IDirect3DDevice
*create_device(IDirectDraw
*ddraw
, HWND window
, DWORD coop_level
)
234 IDirectDrawSurface
*surface
, *ds
;
235 IDirect3DDevice
*device
= NULL
;
236 DDSURFACEDESC surface_desc
;
241 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, coop_level
);
242 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
244 memset(&surface_desc
, 0, sizeof(surface_desc
));
245 surface_desc
.dwSize
= sizeof(surface_desc
);
246 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
247 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
248 surface_desc
.dwWidth
= 640;
249 surface_desc
.dwHeight
= 480;
251 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
252 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
254 if (coop_level
& DDSCL_NORMAL
)
256 IDirectDrawClipper
*clipper
;
258 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
259 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
260 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
261 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
262 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
263 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
264 IDirectDrawClipper_Release(clipper
);
267 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
270 IDirectDrawSurface_Release(surface
);
274 hr
= IDirect3D_EnumDevices(d3d
, enum_z_fmt
, &z_depth
);
275 ok(SUCCEEDED(hr
), "Failed to enumerate z-formats, hr %#x.\n", hr
);
276 IDirect3D_Release(d3d
);
277 if (FAILED(hr
) || !z_depth
)
279 IDirectDrawSurface_Release(surface
);
283 memset(&surface_desc
, 0, sizeof(surface_desc
));
284 surface_desc
.dwSize
= sizeof(surface_desc
);
285 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
286 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
287 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
288 surface_desc
.dwWidth
= 640;
289 surface_desc
.dwHeight
= 480;
290 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
291 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
294 IDirectDrawSurface_Release(surface
);
298 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
299 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
300 IDirectDrawSurface_Release(ds
);
303 IDirectDrawSurface_Release(surface
);
307 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DHALDevice
, (void **)&device
);
308 IDirectDrawSurface_Release(surface
);
315 static IDirect3DViewport
*create_viewport(IDirect3DDevice
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
317 IDirect3DViewport
*viewport
;
322 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
323 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
324 hr
= IDirect3D_CreateViewport(d3d
, &viewport
, NULL
);
325 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
326 hr
= IDirect3DDevice_AddViewport(device
, viewport
);
327 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
328 memset(&vp
, 0, sizeof(vp
));
329 vp
.dwSize
= sizeof(vp
);
334 vp
.dvScaleX
= (float)w
/ 2.0f
;
335 vp
.dvScaleY
= (float)h
/ 2.0f
;
340 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
341 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
342 IDirect3D_Release(d3d
);
347 static void viewport_set_background(IDirect3DDevice
*device
, IDirect3DViewport
*viewport
,
348 IDirect3DMaterial
*material
)
350 D3DMATERIALHANDLE material_handle
;
353 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &material_handle
);
354 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
355 hr
= IDirect3DViewport2_SetBackground(viewport
, material_handle
);
356 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
359 static void destroy_viewport(IDirect3DDevice
*device
, IDirect3DViewport
*viewport
)
363 hr
= IDirect3DDevice_DeleteViewport(device
, viewport
);
364 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
365 IDirect3DViewport_Release(viewport
);
368 static IDirect3DMaterial
*create_diffuse_material(IDirect3DDevice
*device
, float r
, float g
, float b
, float a
)
370 IDirect3DMaterial
*material
;
375 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
376 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
377 hr
= IDirect3D_CreateMaterial(d3d
, &material
, NULL
);
378 ok(SUCCEEDED(hr
), "Failed to create material, hr %#x.\n", hr
);
379 memset(&mat
, 0, sizeof(mat
));
380 mat
.dwSize
= sizeof(mat
);
381 U1(U(mat
).diffuse
).r
= r
;
382 U2(U(mat
).diffuse
).g
= g
;
383 U3(U(mat
).diffuse
).b
= b
;
384 U4(U(mat
).diffuse
).a
= a
;
385 hr
= IDirect3DMaterial_SetMaterial(material
, &mat
);
386 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
387 IDirect3D_Release(d3d
);
392 static void destroy_material(IDirect3DMaterial
*material
)
394 IDirect3DMaterial_Release(material
);
397 static const UINT
*expect_messages
;
399 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
401 if (expect_messages
&& message
== *expect_messages
)
404 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
407 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
408 * interface. This prevents subsequent SetCooperativeLevel() calls on a
409 * different window from failing with DDERR_HWNDALREADYSET. */
410 static void fix_wndproc(HWND window
, LONG_PTR proc
)
415 if (!(ddraw
= create_ddraw()))
418 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
419 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
420 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
421 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
422 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
424 IDirectDraw_Release(ddraw
);
427 static HRESULT CALLBACK
restore_callback(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
429 HRESULT hr
= IDirectDrawSurface_Restore(surface
);
430 ok(SUCCEEDED(hr
), "Failed to restore surface, hr %#x.\n", hr
);
431 IDirectDrawSurface_Release(surface
);
436 static HRESULT
restore_surfaces(IDirectDraw
*ddraw
)
438 return IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
,
439 NULL
, NULL
, restore_callback
);
442 static void test_coop_level_create_device_window(void)
444 HWND focus_window
, device_window
;
448 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
449 0, 0, 640, 480, 0, 0, 0, 0);
450 if (!(ddraw
= create_ddraw()))
452 skip("Failed to create a ddraw object, skipping test.\n");
453 DestroyWindow(focus_window
);
457 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
458 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
459 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
460 ok(!device_window
, "Unexpected device window found.\n");
461 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
462 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
463 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
464 ok(!device_window
, "Unexpected device window found.\n");
465 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
466 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
467 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
468 ok(!device_window
, "Unexpected device window found.\n");
469 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
470 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
471 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
472 ok(!device_window
, "Unexpected device window found.\n");
473 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
474 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
475 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
476 ok(!device_window
, "Unexpected device window found.\n");
478 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
479 if (broken(hr
== DDERR_INVALIDPARAMS
))
481 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
482 IDirectDraw_Release(ddraw
);
483 DestroyWindow(focus_window
);
487 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
488 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
489 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
490 ok(!device_window
, "Unexpected device window found.\n");
491 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
492 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
493 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
494 ok(!device_window
, "Unexpected device window found.\n");
496 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
497 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
498 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
499 ok(!device_window
, "Unexpected device window found.\n");
500 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
501 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
502 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
503 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
504 ok(!!device_window
, "Device window not found.\n");
506 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
507 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
508 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
509 ok(!device_window
, "Unexpected device window found.\n");
510 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
511 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
512 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
513 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
514 ok(!!device_window
, "Device window not found.\n");
516 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
517 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
518 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
519 ok(!device_window
, "Unexpected device window found.\n");
520 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
521 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
522 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
523 ok(!device_window
, "Unexpected device window found.\n");
524 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
525 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
526 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
527 ok(!device_window
, "Unexpected device window found.\n");
528 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
529 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
530 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
531 ok(!!device_window
, "Device window not found.\n");
533 IDirectDraw_Release(ddraw
);
534 DestroyWindow(focus_window
);
537 static void test_clipper_blt(void)
539 IDirectDrawSurface
*src_surface
, *dst_surface
;
540 RECT client_rect
, src_rect
;
541 IDirectDrawClipper
*clipper
;
542 DDSURFACEDESC surface_desc
;
543 unsigned int i
, j
, x
, y
;
554 static const DWORD src_data
[] =
556 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
557 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
558 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
560 static const D3DCOLOR expected1
[] =
562 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
563 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
564 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
565 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
567 static const D3DCOLOR expected2
[] =
569 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
570 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
571 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
572 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
575 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
576 10, 10, 640, 480, 0, 0, 0, 0);
577 ShowWindow(window
, SW_SHOW
);
578 if (!(ddraw
= create_ddraw()))
580 skip("Failed to create a ddraw object, skipping test.\n");
581 DestroyWindow(window
);
585 ret
= GetClientRect(window
, &client_rect
);
586 ok(ret
, "Failed to get client rect.\n");
587 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
588 ok(ret
, "Failed to map client rect.\n");
590 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
591 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
593 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
594 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
595 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
596 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
597 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
598 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
599 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
600 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
601 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
602 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
603 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
604 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
605 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
606 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
607 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
608 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
609 rgn_data
->rdh
.rcBound
.left
, rgn_data
->rdh
.rcBound
.top
,
610 rgn_data
->rdh
.rcBound
.right
, rgn_data
->rdh
.rcBound
.bottom
,
611 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
612 HeapFree(GetProcessHeap(), 0, rgn_data
);
614 r1
= CreateRectRgn(0, 0, 320, 240);
615 ok(!!r1
, "Failed to create region.\n");
616 r2
= CreateRectRgn(320, 240, 640, 480);
617 ok(!!r2
, "Failed to create region.\n");
618 CombineRgn(r1
, r1
, r2
, RGN_OR
);
619 ret
= GetRegionData(r1
, 0, NULL
);
620 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
621 ret
= GetRegionData(r1
, ret
, rgn_data
);
622 ok(!!ret
, "Failed to get region data.\n");
627 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
628 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
629 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
630 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
631 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
632 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
634 HeapFree(GetProcessHeap(), 0, rgn_data
);
636 memset(&surface_desc
, 0, sizeof(surface_desc
));
637 surface_desc
.dwSize
= sizeof(surface_desc
);
638 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
639 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
640 surface_desc
.dwWidth
= 640;
641 surface_desc
.dwHeight
= 480;
642 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
643 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
644 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
645 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
646 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
647 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
649 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
650 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
651 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
652 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
654 memset(&fx
, 0, sizeof(fx
));
655 fx
.dwSize
= sizeof(fx
);
656 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
657 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
658 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
659 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
661 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
662 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
663 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
664 ptr
= surface_desc
.lpSurface
;
665 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
666 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
667 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
668 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
669 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
671 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
672 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
674 SetRect(&src_rect
, 1, 1, 5, 2);
675 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
676 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
677 for (i
= 0; i
< 4; ++i
)
679 for (j
= 0; j
< 4; ++j
)
681 x
= 80 * ((2 * j
) + 1);
682 y
= 60 * ((2 * i
) + 1);
683 color
= get_surface_color(dst_surface
, x
, y
);
684 ok(compare_color(color
, expected1
[i
* 4 + j
], 1),
685 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
689 U5(fx
).dwFillColor
= 0xff0000ff;
690 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
691 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
692 for (i
= 0; i
< 4; ++i
)
694 for (j
= 0; j
< 4; ++j
)
696 x
= 80 * ((2 * j
) + 1);
697 y
= 60 * ((2 * i
) + 1);
698 color
= get_surface_color(dst_surface
, x
, y
);
699 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
700 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
704 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
705 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#x.\n", hr
);
707 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
708 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
709 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
710 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
711 DestroyWindow(window
);
712 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
713 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
714 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
715 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
716 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
717 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
718 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
719 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
720 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
721 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
722 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
723 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
725 IDirectDrawSurface_Release(dst_surface
);
726 IDirectDrawSurface_Release(src_surface
);
727 IDirectDrawClipper_Release(clipper
);
728 IDirectDraw_Release(ddraw
);
731 static void test_coop_level_d3d_state(void)
733 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
734 IDirectDrawSurface
*rt
, *surface
;
735 IDirect3DMaterial
*background
;
736 IDirect3DViewport
*viewport
;
737 IDirect3DDevice
*device
;
738 D3DMATERIAL material
;
744 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
745 0, 0, 640, 480, 0, 0, 0, 0);
746 if (!(ddraw
= create_ddraw()))
748 skip("Failed to create a ddraw object, skipping test.\n");
749 DestroyWindow(window
);
752 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
754 skip("Failed to create a 3D device, skipping test.\n");
755 IDirectDraw_Release(ddraw
);
756 DestroyWindow(window
);
760 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
761 viewport
= create_viewport(device
, 0, 0, 640, 480);
762 viewport_set_background(device
, viewport
, background
);
764 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
765 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
766 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
767 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
768 color
= get_surface_color(rt
, 320, 240);
769 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
771 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
772 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
773 hr
= IDirectDrawSurface_IsLost(rt
);
774 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
775 hr
= restore_surfaces(ddraw
);
776 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
778 memset(&material
, 0, sizeof(material
));
779 material
.dwSize
= sizeof(material
);
780 U1(U(material
).diffuse
).r
= 0.0f
;
781 U2(U(material
).diffuse
).g
= 1.0f
;
782 U3(U(material
).diffuse
).b
= 0.0f
;
783 U4(U(material
).diffuse
).a
= 1.0f
;
784 hr
= IDirect3DMaterial_SetMaterial(background
, &material
);
785 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
787 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&surface
);
788 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
789 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
790 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
791 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
792 color
= get_surface_color(rt
, 320, 240);
793 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
795 destroy_viewport(device
, viewport
);
796 destroy_material(background
);
797 IDirectDrawSurface_Release(surface
);
798 IDirectDrawSurface_Release(rt
);
799 IDirect3DDevice_Release(device
);
800 IDirectDraw_Release(ddraw
);
801 DestroyWindow(window
);
804 static void test_surface_interface_mismatch(void)
806 IDirectDraw
*ddraw
= NULL
;
807 IDirect3D
*d3d
= NULL
;
808 IDirectDrawSurface
*surface
= NULL
, *ds
;
809 IDirectDrawSurface3
*surface3
= NULL
;
810 IDirect3DDevice
*device
= NULL
;
811 IDirect3DViewport
*viewport
= NULL
;
812 IDirect3DMaterial
*background
= NULL
;
813 DDSURFACEDESC surface_desc
;
819 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
821 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
822 0, 0, 640, 480, 0, 0, 0, 0);
824 if (!(ddraw
= create_ddraw()))
826 skip("Failed to create a ddraw object, skipping test.\n");
830 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
831 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
833 memset(&surface_desc
, 0, sizeof(surface_desc
));
834 surface_desc
.dwSize
= sizeof(surface_desc
);
835 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
836 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
837 surface_desc
.dwWidth
= 640;
838 surface_desc
.dwHeight
= 480;
840 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
841 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
843 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
846 skip("Failed to get the IDirectDrawSurface3 interface, skipping test.\n");
850 if (FAILED(hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
)))
852 skip("D3D interface is not available, skipping test.\n");
856 hr
= IDirect3D_EnumDevices(d3d
, enum_z_fmt
, &z_depth
);
857 if (FAILED(hr
) || !z_depth
)
859 skip("No depth buffer formats available, skipping test.\n");
863 memset(&surface_desc
, 0, sizeof(surface_desc
));
864 surface_desc
.dwSize
= sizeof(surface_desc
);
865 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
866 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
867 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
868 surface_desc
.dwWidth
= 640;
869 surface_desc
.dwHeight
= 480;
870 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
871 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
875 /* Using a different surface interface version still works */
876 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
877 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
878 refcount
= IDirectDrawSurface_Release(ds
);
879 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
884 hr
= IDirectDrawSurface3_QueryInterface(surface3
, &IID_IDirect3DHALDevice
, (void **)&device
);
885 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
889 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
890 viewport
= create_viewport(device
, 0, 0, 640, 480);
891 viewport_set_background(device
, viewport
, background
);
893 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
894 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
895 color
= get_surface_color(surface
, 320, 240);
896 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
900 destroy_viewport(device
, viewport
);
902 destroy_material(background
);
903 if (surface3
) IDirectDrawSurface3_Release(surface3
);
904 if (surface
) IDirectDrawSurface_Release(surface
);
905 if (device
) IDirect3DDevice_Release(device
);
906 if (d3d
) IDirect3D_Release(d3d
);
907 if (ddraw
) IDirectDraw_Release(ddraw
);
908 DestroyWindow(window
);
911 static void test_coop_level_threaded(void)
913 struct create_window_thread_param p
;
917 if (!(ddraw
= create_ddraw()))
919 skip("Failed to create a ddraw object, skipping test.\n");
922 create_window_thread(&p
);
924 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
925 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
927 IDirectDraw_Release(ddraw
);
928 destroy_window_thread(&p
);
931 static ULONG
get_refcount(IUnknown
*test_iface
)
933 IUnknown_AddRef(test_iface
);
934 return IUnknown_Release(test_iface
);
937 static void test_viewport(void)
943 IDirect3DViewport
*viewport
, *another_vp
;
944 IDirect3DViewport2
*viewport2
;
945 IDirect3DViewport3
*viewport3
;
946 IDirectDrawGammaControl
*gamma
;
948 IDirect3DDevice
*device
;
951 if (!(ddraw
= create_ddraw()))
953 skip("Failed to create a ddraw object, skipping test.\n");
956 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
957 0, 0, 640, 480, 0, 0, 0, 0);
958 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
960 skip("Failed to create a 3D device, skipping test.\n");
961 IDirectDraw_Release(ddraw
);
962 DestroyWindow(window
);
966 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
967 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
968 ref
= get_refcount((IUnknown
*) d3d
);
969 ok(ref
== 2, "IDirect3D refcount is %d\n", ref
);
971 hr
= IDirect3D_CreateViewport(d3d
, &viewport
, NULL
);
972 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
973 ref
= get_refcount((IUnknown
*)viewport
);
974 ok(ref
== 1, "Initial IDirect3DViewport refcount is %u\n", ref
);
975 ref
= get_refcount((IUnknown
*)d3d
);
976 ok(ref
== 2, "IDirect3D refcount is %u\n", ref
);
978 /* E_FAIL return values are returned by Winetestbot Windows NT machines. While not supporting
979 * newer interfaces is legitimate for old ddraw versions, E_FAIL violates Microsoft's rules
980 * for QueryInterface, hence the broken() */
981 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
982 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
983 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_FAIL
), "Got unexpected hr %#x.\n", hr
);
984 ok(gamma
== NULL
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
985 if (SUCCEEDED(hr
)) IDirectDrawGammaControl_Release(gamma
);
986 /* NULL iid: Segfaults */
988 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirect3DViewport2
, (void **)&viewport2
);
989 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
|| broken(hr
== E_FAIL
),
990 "Failed to QI IDirect3DViewport2, hr %#x.\n", hr
);
993 ref
= get_refcount((IUnknown
*)viewport
);
994 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
995 ref
= get_refcount((IUnknown
*)viewport2
);
996 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
997 IDirect3DViewport2_Release(viewport2
);
1001 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirect3DViewport3
, (void **)&viewport3
);
1002 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
|| broken(hr
== E_FAIL
),
1003 "Failed to QI IDirect3DViewport3, hr %#x.\n", hr
);
1006 ref
= get_refcount((IUnknown
*)viewport
);
1007 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
1008 ref
= get_refcount((IUnknown
*)viewport3
);
1009 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1010 IDirect3DViewport3_Release(viewport3
);
1013 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IUnknown
, (void **)&unknown
);
1014 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#x.\n", hr
);
1017 ref
= get_refcount((IUnknown
*)viewport
);
1018 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
1019 ref
= get_refcount(unknown
);
1020 ok(ref
== 2, "IUnknown refcount is %u\n", ref
);
1021 IUnknown_Release(unknown
);
1024 /* AddViewport(NULL): Segfault */
1025 hr
= IDirect3DDevice_DeleteViewport(device
, NULL
);
1026 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1028 hr
= IDirect3D_CreateViewport(d3d
, &another_vp
, NULL
);
1029 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1031 hr
= IDirect3DDevice_AddViewport(device
, viewport
);
1032 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1033 ref
= get_refcount((IUnknown
*) viewport
);
1034 ok(ref
== 2, "IDirect3DViewport refcount is %d\n", ref
);
1035 hr
= IDirect3DDevice_AddViewport(device
, another_vp
);
1036 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1037 ref
= get_refcount((IUnknown
*) another_vp
);
1038 ok(ref
== 2, "IDirect3DViewport refcount is %d\n", ref
);
1040 hr
= IDirect3DDevice_DeleteViewport(device
, another_vp
);
1041 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#x.\n", hr
);
1042 ref
= get_refcount((IUnknown
*) another_vp
);
1043 ok(ref
== 1, "IDirect3DViewport refcount is %d\n", ref
);
1045 IDirect3DDevice_Release(device
);
1046 ref
= get_refcount((IUnknown
*) viewport
);
1047 ok(ref
== 1, "IDirect3DViewport refcount is %d\n", ref
);
1049 IDirect3DViewport_Release(another_vp
);
1050 IDirect3D_Release(d3d
);
1051 IDirect3DViewport_Release(viewport
);
1052 DestroyWindow(window
);
1053 IDirectDraw_Release(ddraw
);
1056 static void test_zenable(void)
1058 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1059 static D3DTLVERTEX tquad
[] =
1061 {{ 0.0f
}, {480.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1062 {{ 0.0f
}, { 0.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1063 {{640.0f
}, {480.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1064 {{640.0f
}, { 0.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1066 IDirect3DExecuteBuffer
*execute_buffer
;
1067 D3DEXECUTEBUFFERDESC exec_desc
;
1068 IDirect3DMaterial
*background
;
1069 IDirect3DViewport
*viewport
;
1070 IDirect3DDevice
*device
;
1071 IDirectDrawSurface
*rt
;
1081 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1082 0, 0, 640, 480, 0, 0, 0, 0);
1083 if (!(ddraw
= create_ddraw()))
1085 skip("Failed to create a ddraw object, skipping test.\n");
1086 DestroyWindow(window
);
1089 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1091 skip("Failed to create a 3D device, skipping test.\n");
1092 IDirectDraw_Release(ddraw
);
1093 DestroyWindow(window
);
1097 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1098 viewport
= create_viewport(device
, 0, 0, 640, 480);
1099 viewport_set_background(device
, viewport
, background
);
1101 memset(&exec_desc
, 0, sizeof(exec_desc
));
1102 exec_desc
.dwSize
= sizeof(exec_desc
);
1103 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
1104 exec_desc
.dwBufferSize
= 1024;
1105 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
1107 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
1108 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
1109 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
1110 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
1111 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
1112 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(tquad
);
1113 emit_process_vertices(&ptr
, 0, 4);
1114 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1115 emit_tquad(&ptr
, 0);
1117 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
1118 inst_length
-= sizeof(tquad
);
1119 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
1120 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
1122 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1123 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1124 hr
= IDirect3DDevice_BeginScene(device
);
1125 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1126 set_execute_data(execute_buffer
, 4, sizeof(tquad
), inst_length
);
1127 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1128 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1129 hr
= IDirect3DDevice_EndScene(device
);
1130 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1132 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1133 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1134 for (i
= 0; i
< 4; ++i
)
1136 for (j
= 0; j
< 4; ++j
)
1138 x
= 80 * ((2 * j
) + 1);
1139 y
= 60 * ((2 * i
) + 1);
1140 color
= get_surface_color(rt
, x
, y
);
1141 ok(compare_color(color
, 0x0000ff00, 1),
1142 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1145 IDirectDrawSurface_Release(rt
);
1147 destroy_viewport(device
, viewport
);
1148 IDirect3DExecuteBuffer_Release(execute_buffer
);
1149 destroy_material(background
);
1150 IDirect3DDevice_Release(device
);
1151 IDirectDraw_Release(ddraw
);
1152 DestroyWindow(window
);
1155 static void test_ck_rgba(void)
1157 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1158 static D3DTLVERTEX tquad
[] =
1160 {{ 0.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1161 {{ 0.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1162 {{640.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1163 {{640.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1164 {{ 0.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1165 {{ 0.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1166 {{640.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1167 {{640.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1171 D3DCOLOR fill_color
;
1179 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x000000ff},
1180 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x000000ff},
1181 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00},
1182 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1183 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00807f00},
1184 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x0000ff00},
1185 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00},
1186 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1189 IDirect3DExecuteBuffer
*execute_buffer
;
1190 D3DTEXTUREHANDLE texture_handle
;
1191 D3DEXECUTEBUFFERDESC exec_desc
;
1192 IDirect3DMaterial
*background
;
1193 IDirectDrawSurface
*surface
;
1194 IDirect3DViewport
*viewport
;
1195 DDSURFACEDESC surface_desc
;
1196 IDirect3DTexture
*texture
;
1197 IDirect3DDevice
*device
;
1198 IDirectDrawSurface
*rt
;
1206 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1207 0, 0, 640, 480, 0, 0, 0, 0);
1208 if (!(ddraw
= create_ddraw()))
1210 skip("Failed to create a ddraw object, skipping test.\n");
1211 DestroyWindow(window
);
1214 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1216 skip("Failed to create a 3D device, skipping test.\n");
1217 IDirectDraw_Release(ddraw
);
1218 DestroyWindow(window
);
1222 background
= create_diffuse_material(device
, 1.0, 0.0f
, 0.0f
, 1.0f
);
1223 viewport
= create_viewport(device
, 0, 0, 640, 480);
1224 viewport_set_background(device
, viewport
, background
);
1226 memset(&surface_desc
, 0, sizeof(surface_desc
));
1227 surface_desc
.dwSize
= sizeof(surface_desc
);
1228 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1229 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1230 surface_desc
.dwWidth
= 256;
1231 surface_desc
.dwHeight
= 256;
1232 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1233 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1234 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1235 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1236 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1237 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1238 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1239 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1240 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1241 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1242 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1243 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
1244 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1245 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
1246 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1247 IDirect3DTexture_Release(texture
);
1249 memset(&exec_desc
, 0, sizeof(exec_desc
));
1250 exec_desc
.dwSize
= sizeof(exec_desc
);
1251 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
1252 exec_desc
.dwBufferSize
= 1024;
1253 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
1254 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
1255 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
1257 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1258 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1260 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
1262 UINT draw1_len
, draw2_len
;
1265 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
1266 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
1267 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
1268 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(tquad
);
1269 emit_process_vertices(&ptr
, 0, 4);
1270 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1271 emit_set_rs(&ptr
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1272 emit_set_rs(&ptr
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1273 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1274 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1275 emit_tquad(&ptr
, 0);
1277 draw1_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- sizeof(tquad
);
1278 emit_process_vertices(&ptr
, 4, 4);
1279 emit_tquad(&ptr
, 0);
1280 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1282 draw2_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw1_len
;
1283 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
1284 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
1286 memset(&fx
, 0, sizeof(fx
));
1287 fx
.dwSize
= sizeof(fx
);
1288 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1289 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1290 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1292 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
1293 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1294 hr
= IDirect3DDevice_BeginScene(device
);
1295 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1296 set_execute_data(execute_buffer
, 8, sizeof(tquad
), draw1_len
);
1297 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1298 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1299 hr
= IDirect3DDevice_EndScene(device
);
1300 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1302 color
= get_surface_color(rt
, 320, 240);
1304 todo_wine
ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1305 tests
[i
].result1
, i
, color
);
1307 ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1308 tests
[i
].result1
, i
, color
);
1310 U5(fx
).dwFillColor
= 0xff0000ff;
1311 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1312 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1314 hr
= IDirect3DDevice_BeginScene(device
);
1315 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1316 set_execute_data(execute_buffer
, 8, sizeof(tquad
) + draw1_len
, draw2_len
);
1317 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1318 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1319 hr
= IDirect3DDevice_EndScene(device
);
1320 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1322 /* This tests that fragments that are masked out by the color key are
1323 * discarded, instead of just fully transparent. */
1324 color
= get_surface_color(rt
, 320, 240);
1326 todo_wine
ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1327 tests
[i
].result2
, i
, color
);
1329 ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1330 tests
[i
].result2
, i
, color
);
1333 IDirectDrawSurface_Release(rt
);
1334 IDirect3DExecuteBuffer_Release(execute_buffer
);
1335 IDirectDrawSurface_Release(surface
);
1336 destroy_viewport(device
, viewport
);
1337 destroy_material(background
);
1338 IDirect3DDevice_Release(device
);
1339 IDirectDraw_Release(ddraw
);
1340 DestroyWindow(window
);
1343 static void test_ck_default(void)
1345 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1346 static D3DTLVERTEX tquad
[] =
1348 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1349 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1350 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1351 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1353 IDirect3DExecuteBuffer
*execute_buffer
;
1354 IDirectDrawSurface
*surface
, *rt
;
1355 D3DTEXTUREHANDLE texture_handle
;
1356 D3DEXECUTEBUFFERDESC exec_desc
;
1357 IDirect3DMaterial
*background
;
1358 UINT draw1_offset
, draw1_len
;
1359 UINT draw2_offset
, draw2_len
;
1360 UINT draw3_offset
, draw3_len
;
1361 UINT draw4_offset
, draw4_len
;
1362 IDirect3DViewport
*viewport
;
1363 DDSURFACEDESC surface_desc
;
1364 IDirect3DTexture
*texture
;
1365 IDirect3DDevice
*device
;
1373 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1374 0, 0, 640, 480, 0, 0, 0, 0);
1376 if (!(ddraw
= create_ddraw()))
1378 skip("Failed to create a ddraw object, skipping test.\n");
1379 DestroyWindow(window
);
1382 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1384 skip("Failed to create a 3D device, skipping test.\n");
1385 IDirectDraw_Release(ddraw
);
1386 DestroyWindow(window
);
1390 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1391 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1393 background
= create_diffuse_material(device
, 0.0, 1.0f
, 0.0f
, 1.0f
);
1394 viewport
= create_viewport(device
, 0, 0, 640, 480);
1395 viewport_set_background(device
, viewport
, background
);
1397 memset(&surface_desc
, 0, sizeof(surface_desc
));
1398 surface_desc
.dwSize
= sizeof(surface_desc
);
1399 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1400 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1401 surface_desc
.dwWidth
= 256;
1402 surface_desc
.dwHeight
= 256;
1403 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1404 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1405 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1406 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1407 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1408 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1409 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
1410 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
1411 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1412 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1413 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
1414 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1415 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
1416 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1417 IDirect3DTexture_Release(texture
);
1419 memset(&fx
, 0, sizeof(fx
));
1420 fx
.dwSize
= sizeof(fx
);
1421 U5(fx
).dwFillColor
= 0x000000ff;
1422 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1423 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
1425 memset(&exec_desc
, 0, sizeof(exec_desc
));
1426 exec_desc
.dwSize
= sizeof(exec_desc
);
1427 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
1428 exec_desc
.dwBufferSize
= 1024;
1429 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
1430 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
1431 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
1433 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
1434 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
1435 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
1436 ptr
= (BYTE
*)exec_desc
.lpData
+ sizeof(tquad
);
1437 emit_process_vertices(&ptr
, 0, 4);
1438 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1439 emit_tquad(&ptr
, 0);
1441 draw1_offset
= sizeof(tquad
);
1442 draw1_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw1_offset
;
1443 emit_process_vertices(&ptr
, 0, 4);
1444 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, FALSE
);
1445 emit_tquad(&ptr
, 0);
1447 draw2_offset
= draw1_offset
+ draw1_len
;
1448 draw2_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw2_offset
;
1449 emit_process_vertices(&ptr
, 0, 4);
1450 emit_tquad(&ptr
, 0);
1452 draw3_offset
= draw2_offset
+ draw2_len
;
1453 draw3_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw3_offset
;
1454 emit_process_vertices(&ptr
, 0, 4);
1455 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
1456 emit_tquad(&ptr
, 0);
1457 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1459 draw4_offset
= draw3_offset
+ draw3_len
;
1460 draw4_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw4_offset
;
1461 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
1462 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
1464 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1465 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1466 hr
= IDirect3DDevice_BeginScene(device
);
1467 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1468 set_execute_data(execute_buffer
, 4, draw1_offset
, draw1_len
);
1469 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1470 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1471 hr
= IDirect3DDevice_EndScene(device
);
1472 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1473 color
= get_surface_color(rt
, 320, 240);
1474 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1476 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1477 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1478 hr
= IDirect3DDevice_BeginScene(device
);
1479 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1480 set_execute_data(execute_buffer
, 4, draw2_offset
, draw2_len
);
1481 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1482 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1483 hr
= IDirect3DDevice_EndScene(device
);
1484 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1485 color
= get_surface_color(rt
, 320, 240);
1486 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1488 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1489 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1490 hr
= IDirect3DDevice_BeginScene(device
);
1491 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1492 set_execute_data(execute_buffer
, 4, draw3_offset
, draw3_len
);
1493 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1494 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1495 hr
= IDirect3DDevice_EndScene(device
);
1496 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1497 color
= get_surface_color(rt
, 320, 240);
1498 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1500 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1501 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1502 hr
= IDirect3DDevice_BeginScene(device
);
1503 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1504 set_execute_data(execute_buffer
, 4, draw4_offset
, draw4_len
);
1505 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1506 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1507 hr
= IDirect3DDevice_EndScene(device
);
1508 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1509 color
= get_surface_color(rt
, 320, 240);
1510 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1512 IDirect3DExecuteBuffer_Release(execute_buffer
);
1513 IDirectDrawSurface_Release(surface
);
1514 destroy_viewport(device
, viewport
);
1515 destroy_material(background
);
1516 IDirectDrawSurface_Release(rt
);
1517 IDirect3DDevice_Release(device
);
1518 IDirectDraw_Release(ddraw
);
1519 DestroyWindow(window
);
1522 static void test_ck_complex(void)
1524 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
1525 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
1526 DDSURFACEDESC surface_desc
;
1527 IDirect3DDevice
*device
;
1528 DDCOLORKEY color_key
;
1535 if (!(ddraw
= create_ddraw()))
1537 skip("Failed to create a ddraw object, skipping test.\n");
1541 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1542 0, 0, 640, 480, 0, 0, 0, 0);
1543 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
1545 skip("Failed to create a 3D device, skipping test.\n");
1546 DestroyWindow(window
);
1547 IDirectDraw2_Release(ddraw
);
1550 IDirect3DDevice_Release(device
);
1552 memset(&surface_desc
, 0, sizeof(surface_desc
));
1553 surface_desc
.dwSize
= sizeof(surface_desc
);
1554 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1555 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
1556 surface_desc
.dwWidth
= 128;
1557 surface_desc
.dwHeight
= 128;
1558 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1559 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1561 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1562 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1563 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1564 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1565 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1566 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1567 memset(&color_key
, 0, sizeof(color_key
));
1568 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1569 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1570 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1571 color_key
.dwColorSpaceLowValue
);
1572 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1573 color_key
.dwColorSpaceHighValue
);
1576 IDirectDrawSurface_AddRef(mipmap
);
1577 for (i
= 0; i
< 7; ++i
)
1579 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
1580 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
1582 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1583 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
1584 color_key
.dwColorSpaceLowValue
= 0x000000ff;
1585 color_key
.dwColorSpaceHighValue
= 0x000000ff;
1586 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1587 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x, i %u.\n", hr
, i
);
1588 memset(&color_key
, 0, sizeof(color_key
));
1589 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1590 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x, i %u.\n", hr
, i
);
1591 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
1592 color_key
.dwColorSpaceLowValue
, i
);
1593 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
1594 color_key
.dwColorSpaceHighValue
, i
);
1596 IDirectDrawSurface_Release(mipmap
);
1600 memset(&color_key
, 0, sizeof(color_key
));
1601 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1602 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1603 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1604 color_key
.dwColorSpaceLowValue
);
1605 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1606 color_key
.dwColorSpaceHighValue
);
1608 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
1609 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
1610 IDirectDrawSurface_Release(mipmap
);
1611 refcount
= IDirectDrawSurface_Release(surface
);
1612 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1614 memset(&surface_desc
, 0, sizeof(surface_desc
));
1615 surface_desc
.dwSize
= sizeof(surface_desc
);
1616 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
1617 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
1618 surface_desc
.dwBackBufferCount
= 1;
1619 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1620 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1622 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1623 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1624 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1625 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1626 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1627 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1628 memset(&color_key
, 0, sizeof(color_key
));
1629 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1630 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1631 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1632 color_key
.dwColorSpaceLowValue
);
1633 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1634 color_key
.dwColorSpaceHighValue
);
1636 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
1637 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
1639 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1640 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
1641 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1642 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1643 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1644 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1645 memset(&color_key
, 0, sizeof(color_key
));
1646 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1647 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1648 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1649 color_key
.dwColorSpaceLowValue
);
1650 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1651 color_key
.dwColorSpaceHighValue
);
1653 IDirectDrawSurface_Release(tmp
);
1655 refcount
= IDirectDrawSurface_Release(surface
);
1656 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1657 refcount
= IDirectDraw_Release(ddraw
);
1658 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1659 DestroyWindow(window
);
1665 REFIID refcount_iid
;
1669 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
1670 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
1672 ULONG refcount
, expected_refcount
;
1673 IUnknown
*iface1
, *iface2
;
1677 for (i
= 0; i
< entry_count
; ++i
)
1679 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
1680 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
1683 for (j
= 0; j
< entry_count
; ++j
)
1685 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
1686 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
1689 expected_refcount
= 0;
1690 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
1691 ++expected_refcount
;
1692 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
1693 ++expected_refcount
;
1694 refcount
= IUnknown_Release(iface2
);
1695 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
1696 refcount
, test_name
, i
, j
, expected_refcount
);
1700 expected_refcount
= 0;
1701 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
1702 ++expected_refcount
;
1703 refcount
= IUnknown_Release(iface1
);
1704 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
1705 refcount
, test_name
, i
, expected_refcount
);
1710 static void test_surface_qi(void)
1712 static const struct qi_test tests
[] =
1714 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
1715 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
1716 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
1717 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1718 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
1719 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
1720 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
1721 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
1722 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
1723 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
1724 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
1725 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
1726 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
1727 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
1728 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
1729 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
1730 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
1731 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
1732 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
1733 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
1734 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
1735 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
1736 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
1737 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
1738 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
1739 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
1740 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
1741 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
1742 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
1743 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
1744 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
1745 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
1746 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
1747 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
1748 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
1751 IDirectDrawSurface
*surface
;
1752 DDSURFACEDESC surface_desc
;
1753 IDirect3DDevice
*device
;
1758 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
1760 win_skip("DirectDrawCreateEx not available, skipping test.\n");
1764 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1765 0, 0, 640, 480, 0, 0, 0, 0);
1766 if (!(ddraw
= create_ddraw()))
1768 skip("Failed to create a ddraw object, skipping test.\n");
1769 DestroyWindow(window
);
1772 /* Try to create a D3D device to see if the ddraw implementation supports
1773 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
1774 * doesn't support e.g. the IDirect3DTexture interfaces. */
1775 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1777 skip("Failed to create a 3D device, skipping test.\n");
1778 IDirectDraw_Release(ddraw
);
1779 DestroyWindow(window
);
1782 IDirect3DDevice_Release(device
);
1784 memset(&surface_desc
, 0, sizeof(surface_desc
));
1785 surface_desc
.dwSize
= sizeof(surface_desc
);
1786 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1787 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1788 surface_desc
.dwWidth
= 512;
1789 surface_desc
.dwHeight
= 512;
1790 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1791 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1793 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface
, tests
, sizeof(tests
) / sizeof(*tests
));
1795 IDirectDrawSurface_Release(surface
);
1796 IDirectDraw_Release(ddraw
);
1797 DestroyWindow(window
);
1800 static void test_device_qi(void)
1802 static const struct qi_test tests
[] =
1804 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
1805 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
1806 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
1807 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1808 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
1809 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
1810 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
1811 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
1812 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
1813 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
1814 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
1815 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
1816 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
1817 {&IID_IDirect3DHALDevice
, &IID_IDirectDrawSurface
, S_OK
},
1818 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
1819 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
1820 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
1821 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
1822 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
1823 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
1824 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
1825 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
1826 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
1827 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
1828 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
1829 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
1830 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
1831 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
1832 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
1833 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
1834 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
1835 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
1836 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
1837 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
1838 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
1839 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
1843 IDirect3DDevice
*device
;
1847 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
1849 win_skip("DirectDrawCreateEx not available, skipping test.\n");
1853 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1854 0, 0, 640, 480, 0, 0, 0, 0);
1855 if (!(ddraw
= create_ddraw()))
1857 skip("Failed to create a ddraw object, skipping test.\n");
1858 DestroyWindow(window
);
1861 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1863 skip("Failed to create a 3D device, skipping test.\n");
1864 IDirectDraw_Release(ddraw
);
1865 DestroyWindow(window
);
1869 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirectDrawSurface
, tests
, sizeof(tests
) / sizeof(*tests
));
1871 IDirect3DDevice_Release(device
);
1872 IDirectDraw_Release(ddraw
);
1873 DestroyWindow(window
);
1876 static void test_wndproc(void)
1878 LONG_PTR proc
, ddraw_proc
;
1885 static const UINT messages
[] =
1887 WM_WINDOWPOSCHANGING
,
1890 WM_WINDOWPOSCHANGING
,
1896 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
1897 if (!(ddraw
= create_ddraw()))
1899 skip("Failed to create a ddraw object, skipping test.\n");
1903 wc
.lpfnWndProc
= test_proc
;
1904 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
1905 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
1907 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
1908 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
1910 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1911 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1912 (LONG_PTR
)test_proc
, proc
);
1913 expect_messages
= messages
;
1914 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1915 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1916 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
1917 expect_messages
= NULL
;
1918 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1919 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1920 (LONG_PTR
)test_proc
, proc
);
1921 ref
= IDirectDraw_Release(ddraw
);
1922 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1923 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1924 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1925 (LONG_PTR
)test_proc
, proc
);
1927 /* DDSCL_NORMAL doesn't. */
1928 ddraw
= create_ddraw();
1929 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1930 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1931 (LONG_PTR
)test_proc
, proc
);
1932 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
1933 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1934 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1935 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1936 (LONG_PTR
)test_proc
, proc
);
1937 ref
= IDirectDraw_Release(ddraw
);
1938 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1939 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1940 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1941 (LONG_PTR
)test_proc
, proc
);
1943 /* The original window proc is only restored by ddraw if the current
1944 * window proc matches the one ddraw set. This also affects switching
1945 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
1946 ddraw
= create_ddraw();
1947 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1948 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1949 (LONG_PTR
)test_proc
, proc
);
1950 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1951 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1952 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1953 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1954 (LONG_PTR
)test_proc
, proc
);
1956 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1957 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1958 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1959 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1960 (LONG_PTR
)test_proc
, proc
);
1961 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1962 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1963 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
1964 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1965 (LONG_PTR
)test_proc
, proc
);
1966 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1967 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1968 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1969 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
1970 (LONG_PTR
)DefWindowProcA
, proc
);
1971 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1972 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1973 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)ddraw_proc
);
1974 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
1975 (LONG_PTR
)DefWindowProcA
, proc
);
1976 ref
= IDirectDraw_Release(ddraw
);
1977 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1978 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1979 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1980 (LONG_PTR
)test_proc
, proc
);
1982 ddraw
= create_ddraw();
1983 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1984 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1985 (LONG_PTR
)test_proc
, proc
);
1986 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1987 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1988 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
1989 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1990 (LONG_PTR
)test_proc
, proc
);
1991 ref
= IDirectDraw_Release(ddraw
);
1992 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1993 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1994 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
1995 (LONG_PTR
)DefWindowProcA
, proc
);
1997 fix_wndproc(window
, (LONG_PTR
)test_proc
);
1998 expect_messages
= NULL
;
1999 DestroyWindow(window
);
2000 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2003 static void test_window_style(void)
2005 LONG style
, exstyle
, tmp
;
2006 RECT fullscreen_rect
, r
;
2012 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2013 0, 0, 100, 100, 0, 0, 0, 0);
2014 if (!(ddraw
= create_ddraw()))
2016 skip("Failed to create a ddraw object, skipping test.\n");
2017 DestroyWindow(window
);
2021 style
= GetWindowLongA(window
, GWL_STYLE
);
2022 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2023 SetRect(&fullscreen_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
2025 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2026 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2028 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2029 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2030 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2031 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2033 GetWindowRect(window
, &r
);
2034 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2035 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2036 r
.left
, r
.top
, r
.right
, r
.bottom
);
2037 GetClientRect(window
, &r
);
2038 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2040 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2041 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2043 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2044 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2045 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2046 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2048 ref
= IDirectDraw_Release(ddraw
);
2049 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2051 DestroyWindow(window
);
2054 static void test_redundant_mode_set(void)
2056 DDSURFACEDESC surface_desc
= {0};
2063 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2064 0, 0, 100, 100, 0, 0, 0, 0);
2065 if (!(ddraw
= create_ddraw()))
2067 skip("Failed to create a ddraw object, skipping test.\n");
2068 DestroyWindow(window
);
2072 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2073 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2075 surface_desc
.dwSize
= sizeof(surface_desc
);
2076 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
2077 ok(SUCCEEDED(hr
), "GetDipslayMode failed, hr %#x.\n", hr
);
2079 hr
= IDirectDraw_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2080 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
2081 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2083 GetWindowRect(window
, &r
);
2086 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2087 GetWindowRect(window
, &s
);
2088 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2089 r
.left
, r
.top
, r
.right
, r
.bottom
,
2090 s
.left
, s
.top
, s
.right
, s
.bottom
);
2092 hr
= IDirectDraw_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2093 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
2094 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2096 GetWindowRect(window
, &s
);
2097 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2098 r
.left
, r
.top
, r
.right
, r
.bottom
,
2099 s
.left
, s
.top
, s
.right
, s
.bottom
);
2101 ref
= IDirectDraw_Release(ddraw
);
2102 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2104 DestroyWindow(window
);
2107 static SIZE screen_size
;
2109 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2111 if (message
== WM_SIZE
)
2113 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2114 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2117 return test_proc(hwnd
, message
, wparam
, lparam
);
2120 static void test_coop_level_mode_set(void)
2122 IDirectDrawSurface
*primary
;
2123 RECT fullscreen_rect
, r
, s
;
2131 static const UINT exclusive_messages
[] =
2133 WM_WINDOWPOSCHANGING
,
2134 WM_WINDOWPOSCHANGED
,
2140 static const UINT normal_messages
[] =
2146 if (!(ddraw
= create_ddraw()))
2148 skip("Failed to create a ddraw object, skipping test.\n");
2152 wc
.lpfnWndProc
= mode_set_proc
;
2153 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2154 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2156 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2157 0, 0, 100, 100, 0, 0, 0, 0);
2159 SetRect(&fullscreen_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
2160 SetRect(&s
, 0, 0, 640, 480);
2162 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2163 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2165 GetWindowRect(window
, &r
);
2166 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2167 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2168 r
.left
, r
.top
, r
.right
, r
.bottom
);
2170 memset(&ddsd
, 0, sizeof(ddsd
));
2171 ddsd
.dwSize
= sizeof(ddsd
);
2172 ddsd
.dwFlags
= DDSD_CAPS
;
2173 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2175 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2176 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2177 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2178 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2179 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2180 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2181 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2182 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2184 GetWindowRect(window
, &r
);
2185 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2186 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2187 r
.left
, r
.top
, r
.right
, r
.bottom
);
2189 expect_messages
= exclusive_messages
;
2193 hr
= IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 32);
2194 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2196 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2197 expect_messages
= NULL
;
2198 ok(screen_size
.cx
== s
.right
&& screen_size
.cy
== s
.bottom
,
2199 "Expected screen size %ux%u, got %ux%u.\n",
2200 s
.right
, s
.bottom
, screen_size
.cx
, screen_size
.cy
);
2202 GetWindowRect(window
, &r
);
2203 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2204 s
.left
, s
.top
, s
.right
, s
.bottom
,
2205 r
.left
, r
.top
, r
.right
, r
.bottom
);
2207 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2208 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2209 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2210 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2211 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2212 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2213 IDirectDrawSurface_Release(primary
);
2215 memset(&ddsd
, 0, sizeof(ddsd
));
2216 ddsd
.dwSize
= sizeof(ddsd
);
2217 ddsd
.dwFlags
= DDSD_CAPS
;
2218 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2220 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2221 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2222 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2223 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2224 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2225 s
.right
- s
.left
, ddsd
.dwWidth
);
2226 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2227 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2229 GetWindowRect(window
, &r
);
2230 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2231 s
.left
, s
.top
, s
.right
, s
.bottom
,
2232 r
.left
, r
.top
, r
.right
, r
.bottom
);
2234 expect_messages
= exclusive_messages
;
2238 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2239 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2241 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2242 expect_messages
= NULL
;
2243 ok(screen_size
.cx
== fullscreen_rect
.right
&& screen_size
.cy
== fullscreen_rect
.bottom
,
2244 "Expected screen size %ux%u, got %ux%u.\n",
2245 fullscreen_rect
.right
, fullscreen_rect
.bottom
, screen_size
.cx
, screen_size
.cy
);
2247 GetWindowRect(window
, &r
);
2248 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2249 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2250 r
.left
, r
.top
, r
.right
, r
.bottom
);
2252 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2253 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2254 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2255 s
.right
- s
.left
, ddsd
.dwWidth
);
2256 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2257 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2258 IDirectDrawSurface_Release(primary
);
2260 memset(&ddsd
, 0, sizeof(ddsd
));
2261 ddsd
.dwSize
= sizeof(ddsd
);
2262 ddsd
.dwFlags
= DDSD_CAPS
;
2263 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2265 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2266 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2267 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2268 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2269 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2270 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2271 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2272 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2274 GetWindowRect(window
, &r
);
2275 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2276 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2277 r
.left
, r
.top
, r
.right
, r
.bottom
);
2279 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2280 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2282 GetWindowRect(window
, &r
);
2283 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2284 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2285 r
.left
, r
.top
, r
.right
, r
.bottom
);
2287 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2288 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2289 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2290 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2291 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2292 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2293 IDirectDrawSurface_Release(primary
);
2295 memset(&ddsd
, 0, sizeof(ddsd
));
2296 ddsd
.dwSize
= sizeof(ddsd
);
2297 ddsd
.dwFlags
= DDSD_CAPS
;
2298 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2300 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2301 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2302 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2303 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2304 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2305 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2306 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2307 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2309 GetWindowRect(window
, &r
);
2310 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2311 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2312 r
.left
, r
.top
, r
.right
, r
.bottom
);
2314 expect_messages
= normal_messages
;
2318 hr
= IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 32);
2319 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_NOEXCLUSIVEMODE
) /* NT4 testbot */,
2320 "SetDisplayMode failed, hr %#x.\n", hr
);
2321 if (hr
== DDERR_NOEXCLUSIVEMODE
)
2323 win_skip("Broken SetDisplayMode(), skipping remaining tests.\n");
2324 IDirectDrawSurface_Release(primary
);
2325 IDirectDraw_Release(ddraw
);
2329 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2330 expect_messages
= NULL
;
2331 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2333 GetWindowRect(window
, &r
);
2334 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2335 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2336 r
.left
, r
.top
, r
.right
, r
.bottom
);
2338 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2339 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2340 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2341 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2342 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2343 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2344 IDirectDrawSurface_Release(primary
);
2346 memset(&ddsd
, 0, sizeof(ddsd
));
2347 ddsd
.dwSize
= sizeof(ddsd
);
2348 ddsd
.dwFlags
= DDSD_CAPS
;
2349 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2351 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2352 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2353 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2354 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2355 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2356 s
.right
- s
.left
, ddsd
.dwWidth
);
2357 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2358 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2360 GetWindowRect(window
, &r
);
2361 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2362 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2363 r
.left
, r
.top
, r
.right
, r
.bottom
);
2365 expect_messages
= normal_messages
;
2369 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2370 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2372 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2373 expect_messages
= NULL
;
2374 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
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 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2382 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2383 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2384 s
.right
- s
.left
, ddsd
.dwWidth
);
2385 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2386 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2387 IDirectDrawSurface_Release(primary
);
2389 memset(&ddsd
, 0, sizeof(ddsd
));
2390 ddsd
.dwSize
= sizeof(ddsd
);
2391 ddsd
.dwFlags
= DDSD_CAPS
;
2392 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2394 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2395 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2396 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2397 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2398 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2399 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2400 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2401 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2403 GetWindowRect(window
, &r
);
2404 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2405 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2406 r
.left
, r
.top
, r
.right
, r
.bottom
);
2408 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
2409 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
2410 * not DDSCL_FULLSCREEN. */
2411 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2412 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2414 GetWindowRect(window
, &r
);
2415 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2416 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2417 r
.left
, r
.top
, r
.right
, r
.bottom
);
2419 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2420 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2421 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2422 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2423 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2424 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2425 IDirectDrawSurface_Release(primary
);
2427 memset(&ddsd
, 0, sizeof(ddsd
));
2428 ddsd
.dwSize
= sizeof(ddsd
);
2429 ddsd
.dwFlags
= DDSD_CAPS
;
2430 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2432 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2433 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2434 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2435 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2436 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2437 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2438 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2439 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2441 GetWindowRect(window
, &r
);
2442 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2443 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2444 r
.left
, r
.top
, r
.right
, r
.bottom
);
2446 expect_messages
= normal_messages
;
2450 hr
= IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 32);
2451 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2453 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2454 expect_messages
= NULL
;
2455 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2457 GetWindowRect(window
, &r
);
2458 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2459 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2460 r
.left
, r
.top
, r
.right
, r
.bottom
);
2462 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2463 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2464 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2465 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2466 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2467 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2468 IDirectDrawSurface_Release(primary
);
2470 memset(&ddsd
, 0, sizeof(ddsd
));
2471 ddsd
.dwSize
= sizeof(ddsd
);
2472 ddsd
.dwFlags
= DDSD_CAPS
;
2473 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2475 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2476 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2477 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2478 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2479 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2480 s
.right
- s
.left
, ddsd
.dwWidth
);
2481 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2482 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2484 GetWindowRect(window
, &r
);
2485 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2486 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2487 r
.left
, r
.top
, r
.right
, r
.bottom
);
2489 expect_messages
= normal_messages
;
2493 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2494 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2496 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2497 expect_messages
= NULL
;
2498 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2500 GetWindowRect(window
, &r
);
2501 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2502 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2503 r
.left
, r
.top
, r
.right
, r
.bottom
);
2505 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2506 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2507 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2508 s
.right
- s
.left
, ddsd
.dwWidth
);
2509 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2510 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2511 IDirectDrawSurface_Release(primary
);
2513 memset(&ddsd
, 0, sizeof(ddsd
));
2514 ddsd
.dwSize
= sizeof(ddsd
);
2515 ddsd
.dwFlags
= DDSD_CAPS
;
2516 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2518 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2519 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2520 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2521 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2522 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2523 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2524 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2525 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2526 IDirectDrawSurface_Release(primary
);
2528 GetWindowRect(window
, &r
);
2529 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2530 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2531 r
.left
, r
.top
, r
.right
, r
.bottom
);
2533 /* Unlike ddraw2-7, changing from EXCLUSIVE to NORMAL does not restore the resolution */
2534 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2535 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2536 hr
= IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 32);
2537 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2539 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2540 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2542 memset(&ddsd
, 0, sizeof(ddsd
));
2543 ddsd
.dwSize
= sizeof(ddsd
);
2544 ddsd
.dwFlags
= DDSD_CAPS
;
2545 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2547 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2548 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2549 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2550 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2551 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2552 s
.right
- s
.left
, ddsd
.dwWidth
);
2553 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2554 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2555 IDirectDrawSurface_Release(primary
);
2556 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2557 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2559 ref
= IDirectDraw_Release(ddraw
);
2560 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2562 GetWindowRect(window
, &r
);
2563 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2564 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2565 r
.left
, r
.top
, r
.right
, r
.bottom
);
2568 expect_messages
= NULL
;
2569 DestroyWindow(window
);
2570 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2573 static void test_coop_level_mode_set_multi(void)
2575 IDirectDraw
*ddraw1
, *ddraw2
;
2576 UINT orig_w
, orig_h
, w
, h
;
2581 if (!(ddraw1
= create_ddraw()))
2583 skip("Failed to create a ddraw object, skipping test.\n");
2587 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2588 0, 0, 100, 100, 0, 0, 0, 0);
2590 orig_w
= GetSystemMetrics(SM_CXSCREEN
);
2591 orig_h
= GetSystemMetrics(SM_CYSCREEN
);
2593 /* With just a single ddraw object, the display mode is restored on
2595 hr
= IDirectDraw_SetDisplayMode(ddraw1
, 800, 600, 32);
2596 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_NOEXCLUSIVEMODE
) /* NT4 testbot */,
2597 "SetDisplayMode failed, hr %#x.\n", hr
);
2598 if (hr
== DDERR_NOEXCLUSIVEMODE
)
2600 win_skip("Broken SetDisplayMode(), skipping test.\n");
2601 IDirectDraw_Release(ddraw1
);
2602 DestroyWindow(window
);
2605 w
= GetSystemMetrics(SM_CXSCREEN
);
2606 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2607 h
= GetSystemMetrics(SM_CYSCREEN
);
2608 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2610 ref
= IDirectDraw_Release(ddraw1
);
2611 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2612 w
= GetSystemMetrics(SM_CXSCREEN
);
2613 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2614 h
= GetSystemMetrics(SM_CYSCREEN
);
2615 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2617 /* When there are multiple ddraw objects, the display mode is restored to
2618 * the initial mode, before the first SetDisplayMode() call. */
2619 ddraw1
= create_ddraw();
2620 hr
= IDirectDraw_SetDisplayMode(ddraw1
, 800, 600, 32);
2621 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2622 w
= GetSystemMetrics(SM_CXSCREEN
);
2623 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2624 h
= GetSystemMetrics(SM_CYSCREEN
);
2625 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2627 ddraw2
= create_ddraw();
2628 hr
= IDirectDraw_SetDisplayMode(ddraw2
, 640, 480, 32);
2629 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2630 w
= GetSystemMetrics(SM_CXSCREEN
);
2631 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2632 h
= GetSystemMetrics(SM_CYSCREEN
);
2633 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2635 ref
= IDirectDraw_Release(ddraw2
);
2636 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2637 w
= GetSystemMetrics(SM_CXSCREEN
);
2638 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2639 h
= GetSystemMetrics(SM_CYSCREEN
);
2640 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2642 ref
= IDirectDraw_Release(ddraw1
);
2643 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2644 w
= GetSystemMetrics(SM_CXSCREEN
);
2645 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2646 h
= GetSystemMetrics(SM_CYSCREEN
);
2647 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2649 /* Regardless of release ordering. */
2650 ddraw1
= create_ddraw();
2651 hr
= IDirectDraw_SetDisplayMode(ddraw1
, 800, 600, 32);
2652 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2653 w
= GetSystemMetrics(SM_CXSCREEN
);
2654 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2655 h
= GetSystemMetrics(SM_CYSCREEN
);
2656 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2658 ddraw2
= create_ddraw();
2659 hr
= IDirectDraw_SetDisplayMode(ddraw2
, 640, 480, 32);
2660 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2661 w
= GetSystemMetrics(SM_CXSCREEN
);
2662 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2663 h
= GetSystemMetrics(SM_CYSCREEN
);
2664 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2666 ref
= IDirectDraw_Release(ddraw1
);
2667 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2668 w
= GetSystemMetrics(SM_CXSCREEN
);
2669 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2670 h
= GetSystemMetrics(SM_CYSCREEN
);
2671 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2673 ref
= IDirectDraw_Release(ddraw2
);
2674 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2675 w
= GetSystemMetrics(SM_CXSCREEN
);
2676 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2677 h
= GetSystemMetrics(SM_CYSCREEN
);
2678 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2680 /* But only for ddraw objects that called SetDisplayMode(). */
2681 ddraw1
= create_ddraw();
2682 ddraw2
= create_ddraw();
2683 hr
= IDirectDraw_SetDisplayMode(ddraw2
, 640, 480, 32);
2684 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2685 w
= GetSystemMetrics(SM_CXSCREEN
);
2686 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2687 h
= GetSystemMetrics(SM_CYSCREEN
);
2688 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2690 ref
= IDirectDraw_Release(ddraw1
);
2691 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2692 w
= GetSystemMetrics(SM_CXSCREEN
);
2693 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2694 h
= GetSystemMetrics(SM_CYSCREEN
);
2695 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2697 ref
= IDirectDraw_Release(ddraw2
);
2698 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2699 w
= GetSystemMetrics(SM_CXSCREEN
);
2700 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2701 h
= GetSystemMetrics(SM_CYSCREEN
);
2702 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2704 /* If there's a ddraw object that's currently in exclusive mode, it blocks
2705 * restoring the display mode. */
2706 ddraw1
= create_ddraw();
2707 hr
= IDirectDraw_SetDisplayMode(ddraw1
, 800, 600, 32);
2708 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2709 w
= GetSystemMetrics(SM_CXSCREEN
);
2710 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2711 h
= GetSystemMetrics(SM_CYSCREEN
);
2712 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2714 ddraw2
= create_ddraw();
2715 hr
= IDirectDraw_SetDisplayMode(ddraw2
, 640, 480, 32);
2716 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2717 w
= GetSystemMetrics(SM_CXSCREEN
);
2718 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2719 h
= GetSystemMetrics(SM_CYSCREEN
);
2720 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2722 hr
= IDirectDraw_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2723 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2725 ref
= IDirectDraw_Release(ddraw1
);
2726 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2727 w
= GetSystemMetrics(SM_CXSCREEN
);
2728 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2729 h
= GetSystemMetrics(SM_CYSCREEN
);
2730 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2732 ref
= IDirectDraw_Release(ddraw2
);
2733 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2734 w
= GetSystemMetrics(SM_CXSCREEN
);
2735 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2736 h
= GetSystemMetrics(SM_CYSCREEN
);
2737 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2739 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
2740 ddraw1
= create_ddraw();
2741 hr
= IDirectDraw_SetDisplayMode(ddraw1
, 800, 600, 32);
2742 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2743 w
= GetSystemMetrics(SM_CXSCREEN
);
2744 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2745 h
= GetSystemMetrics(SM_CYSCREEN
);
2746 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2748 hr
= IDirectDraw_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2749 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2751 ddraw2
= create_ddraw();
2752 hr
= IDirectDraw_SetDisplayMode(ddraw2
, 640, 480, 32);
2753 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
2755 ref
= IDirectDraw_Release(ddraw1
);
2756 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2757 w
= GetSystemMetrics(SM_CXSCREEN
);
2758 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2759 h
= GetSystemMetrics(SM_CYSCREEN
);
2760 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2762 ref
= IDirectDraw_Release(ddraw2
);
2763 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2764 w
= GetSystemMetrics(SM_CXSCREEN
);
2765 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2766 h
= GetSystemMetrics(SM_CYSCREEN
);
2767 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2769 DestroyWindow(window
);
2772 static void test_initialize(void)
2778 if (!(ddraw
= create_ddraw()))
2780 skip("Failed to create a ddraw object, skipping test.\n");
2784 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
2785 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
2786 IDirectDraw_Release(ddraw
);
2789 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw
, (void **)&ddraw
);
2790 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw instance, hr %#x.\n", hr
);
2791 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
2794 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
2795 hr
= IDirect3D_Initialize(d3d
, NULL
);
2796 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
2797 IDirect3D_Release(d3d
);
2800 skip("D3D interface is not available, skipping test.\n");
2801 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
2802 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
2803 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
2804 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
2805 IDirectDraw_Release(ddraw
);
2808 if (0) /* This crashes on the W2KPROSP4 testbot. */
2811 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirect3D
, (void **)&d3d
);
2812 ok(hr
== E_NOINTERFACE
, "CoCreateInstance returned hr %#x, expected E_NOINTERFACE.\n", hr
);
2817 static void test_coop_level_surf_create(void)
2819 IDirectDrawSurface
*surface
;
2824 if (!(ddraw
= create_ddraw()))
2826 skip("Failed to create a ddraw object, skipping test.\n");
2830 memset(&ddsd
, 0, sizeof(ddsd
));
2831 ddsd
.dwSize
= sizeof(ddsd
);
2832 ddsd
.dwFlags
= DDSD_CAPS
;
2833 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2834 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
2835 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
2837 IDirectDraw_Release(ddraw
);
2840 static void test_coop_level_multi_window(void)
2842 HWND window1
, window2
;
2846 window1
= CreateWindowA("static", "ddraw_test1", WS_OVERLAPPEDWINDOW
,
2847 0, 0, 640, 480, 0, 0, 0, 0);
2848 window2
= CreateWindowA("static", "ddraw_test2", WS_OVERLAPPEDWINDOW
,
2849 0, 0, 640, 480, 0, 0, 0, 0);
2850 if (!(ddraw
= create_ddraw()))
2852 skip("Failed to create a ddraw object, skipping test.\n");
2853 DestroyWindow(window2
);
2854 DestroyWindow(window1
);
2858 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
2859 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
2860 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
2861 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
2862 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
2863 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
2865 IDirectDraw_Release(ddraw
);
2866 DestroyWindow(window2
);
2867 DestroyWindow(window1
);
2870 static void test_clear_rect_count(void)
2872 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
2873 IDirect3DMaterial
*white
, *red
, *green
, *blue
;
2874 IDirect3DViewport
*viewport
;
2875 IDirect3DDevice
*device
;
2876 IDirectDrawSurface
*rt
;
2882 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2883 0, 0, 640, 480, 0, 0, 0, 0);
2884 if (!(ddraw
= create_ddraw()))
2886 skip("Failed to create a ddraw object, skipping test.\n");
2887 DestroyWindow(window
);
2890 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2892 skip("Failed to create a 3D device, skipping test.\n");
2893 IDirectDraw_Release(ddraw
);
2894 DestroyWindow(window
);
2898 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
2899 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
2901 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
2902 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
2903 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
2904 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
2905 viewport
= create_viewport(device
, 0, 0, 640, 480);
2907 viewport_set_background(device
, viewport
, white
);
2908 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2909 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
2910 viewport_set_background(device
, viewport
, red
);
2911 hr
= IDirect3DViewport_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
2912 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
2913 viewport_set_background(device
, viewport
, green
);
2914 hr
= IDirect3DViewport_Clear(viewport
, 0, NULL
, D3DCLEAR_TARGET
);
2915 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
2916 viewport_set_background(device
, viewport
, blue
);
2917 hr
= IDirect3DViewport_Clear(viewport
, 1, NULL
, D3DCLEAR_TARGET
);
2918 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
2920 color
= get_surface_color(rt
, 320, 240);
2921 ok(compare_color(color
, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", color
);
2923 IDirectDrawSurface_Release(rt
);
2924 destroy_viewport(device
, viewport
);
2925 destroy_material(white
);
2926 destroy_material(red
);
2927 destroy_material(green
);
2928 destroy_material(blue
);
2929 IDirect3DDevice_Release(device
);
2930 IDirectDraw_Release(ddraw
);
2931 DestroyWindow(window
);
2940 } activateapp_testdata
;
2942 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2944 if (message
== WM_ACTIVATEAPP
)
2946 if (activateapp_testdata
.ddraw
)
2949 activateapp_testdata
.received
= FALSE
;
2950 hr
= IDirectDraw_SetCooperativeLevel(activateapp_testdata
.ddraw
,
2951 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
2952 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#x.\n", hr
);
2953 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
2955 activateapp_testdata
.received
= TRUE
;
2958 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
2961 static void test_coop_level_activateapp(void)
2968 IDirectDrawSurface
*surface
;
2970 if (!(ddraw
= create_ddraw()))
2972 skip("Failed to create a ddraw object, skipping test.\n");
2976 wc
.lpfnWndProc
= activateapp_test_proc
;
2977 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2978 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2980 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2981 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2983 /* Exclusive with window already active. */
2984 SetActiveWindow(window
);
2985 activateapp_testdata
.received
= FALSE
;
2986 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2987 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
2988 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
2989 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
2990 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
2992 /* Exclusive with window not active. */
2993 SetActiveWindow(NULL
);
2994 activateapp_testdata
.received
= FALSE
;
2995 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2996 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
2997 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
2998 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
2999 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3001 /* Normal with window not active, then exclusive with the same window. */
3002 SetActiveWindow(NULL
);
3003 activateapp_testdata
.received
= FALSE
;
3004 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3005 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3006 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
3007 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3008 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3009 /* Except in the first SetCooperativeLevel call, Windows XP randomly does not send
3010 * WM_ACTIVATEAPP. Windows 7 sends the message reliably. Mark the XP behavior broken. */
3011 ok(activateapp_testdata
.received
|| broken(!activateapp_testdata
.received
),
3012 "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3013 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3014 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3016 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
3017 SetActiveWindow(NULL
);
3018 activateapp_testdata
.received
= FALSE
;
3019 activateapp_testdata
.ddraw
= ddraw
;
3020 activateapp_testdata
.window
= window
;
3021 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
3022 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3023 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3024 ok(activateapp_testdata
.received
|| broken(!activateapp_testdata
.received
),
3025 "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3026 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3027 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3029 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
3030 * succeeding. Another switch to exclusive and back to normal is needed to release the
3031 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
3032 * WM_ACTIVATEAPP messages. */
3033 activateapp_testdata
.ddraw
= NULL
;
3034 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3035 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3036 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3037 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3039 /* Setting DDSCL_NORMAL with recursive invocation. */
3040 SetActiveWindow(NULL
);
3041 activateapp_testdata
.received
= FALSE
;
3042 activateapp_testdata
.ddraw
= ddraw
;
3043 activateapp_testdata
.window
= window
;
3044 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
3045 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3046 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3047 ok(activateapp_testdata
.received
|| broken(!activateapp_testdata
.received
),
3048 "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3050 /* DDraw is in exlusive mode now. */
3051 memset(&ddsd
, 0, sizeof(ddsd
));
3052 ddsd
.dwSize
= sizeof(ddsd
);
3053 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
3054 ddsd
.dwBackBufferCount
= 1;
3055 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
3056 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3057 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
3058 IDirectDrawSurface_Release(surface
);
3060 /* Recover again, just to be sure. */
3061 activateapp_testdata
.ddraw
= NULL
;
3062 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3063 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3064 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3065 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3067 DestroyWindow(window
);
3068 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3069 IDirectDraw_Release(ddraw
);
3072 struct format_support_check
3074 const DDPIXELFORMAT
*format
;
3078 static HRESULT WINAPI
test_unsupported_formats_cb(DDSURFACEDESC
*desc
, void *ctx
)
3080 struct format_support_check
*format
= ctx
;
3082 if (!memcmp(format
->format
, &desc
->ddpfPixelFormat
, sizeof(*format
->format
)))
3084 format
->supported
= TRUE
;
3085 return DDENUMRET_CANCEL
;
3088 return DDENUMRET_OK
;
3091 static void test_unsupported_formats(void)
3094 BOOL expect_success
;
3097 IDirect3DDevice
*device
;
3098 IDirectDrawSurface
*surface
;
3101 DWORD expected_caps
;
3112 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
3113 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
3119 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
3120 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3124 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
3126 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3127 0, 0, 640, 480, 0, 0, 0, 0);
3128 if (!(ddraw
= create_ddraw()))
3130 skip("Failed to create a ddraw object, skipping test.\n");
3131 DestroyWindow(window
);
3134 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3136 skip("Failed to create a 3D device, skipping test.\n");
3137 IDirectDraw_Release(ddraw
);
3138 DestroyWindow(window
);
3142 for (i
= 0; i
< sizeof(formats
) / sizeof(*formats
); i
++)
3144 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
3145 hr
= IDirect3DDevice_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
3146 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
3148 for (j
= 0; j
< sizeof(caps
) / sizeof(*caps
); j
++)
3150 memset(&ddsd
, 0, sizeof(ddsd
));
3151 ddsd
.dwSize
= sizeof(ddsd
);
3152 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
3153 ddsd
.ddpfPixelFormat
= formats
[i
].fmt
;
3156 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
3158 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
3159 expect_success
= FALSE
;
3161 expect_success
= TRUE
;
3163 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3164 ok(SUCCEEDED(hr
) == expect_success
,
3165 "Got unexpected hr %#x for format %s, caps %#x, expected %s.\n",
3166 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
3170 memset(&ddsd
, 0, sizeof(ddsd
));
3171 ddsd
.dwSize
= sizeof(ddsd
);
3172 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &ddsd
);
3173 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3175 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
3176 expected_caps
= DDSCAPS_VIDEOMEMORY
;
3177 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
3178 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
3179 else if (check
.supported
)
3180 expected_caps
= DDSCAPS_VIDEOMEMORY
;
3182 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
3184 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
3185 "Expected capability %#x, format %s, input cap %#x.\n",
3186 expected_caps
, formats
[i
].name
, caps
[j
]);
3188 IDirectDrawSurface_Release(surface
);
3192 IDirect3DDevice_Release(device
);
3193 IDirectDraw_Release(ddraw
);
3194 DestroyWindow(window
);
3197 static void test_rt_caps(void)
3199 PALETTEENTRY palette_entries
[256];
3200 IDirectDrawPalette
*palette
;
3209 static const DDPIXELFORMAT p8_fmt
=
3211 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
3212 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
3217 const DDPIXELFORMAT
*pf
;
3220 HRESULT create_device_hr
;
3221 BOOL create_may_fail
;
3227 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
3228 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3234 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
3235 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3241 DDSCAPS_OFFSCREENPLAIN
,
3242 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3248 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3249 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3250 D3DERR_SURFACENOTINVIDMEM
,
3255 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3256 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3262 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
3263 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3270 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3277 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3283 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3284 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3285 D3DERR_SURFACENOTINVIDMEM
,
3290 DDSCAPS_SYSTEMMEMORY
,
3291 DDSCAPS_SYSTEMMEMORY
,
3298 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3304 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
3305 ~0U /* AMD r200 */ ,
3306 DDERR_NOPALETTEATTACHED
,
3311 DDSCAPS_OFFSCREENPLAIN
,
3312 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3318 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3319 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3320 DDERR_NOPALETTEATTACHED
,
3325 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3326 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3332 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
3333 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
3335 TRUE
/* AMD Evergreen */,
3339 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
3340 ~0U /* AMD Evergreen */,
3347 ~0U /* AMD Evergreen */,
3353 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
3354 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
3356 TRUE
/* Nvidia Kepler */,
3360 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
3361 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
3363 TRUE
/* Nvidia Kepler */,
3367 if (!(ddraw
= create_ddraw()))
3369 skip("Failed to create a ddraw object, skipping test.\n");
3373 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3374 0, 0, 640, 480, 0, 0, 0, 0);
3375 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3376 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3378 if (FAILED(hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
)))
3380 skip("D3D interface is not available, skipping test.\n");
3384 hr
= IDirect3D_EnumDevices(d3d
, enum_z_fmt
, &z_depth
);
3385 if (FAILED(hr
) || !z_depth
)
3387 skip("No depth buffer formats available, skipping test.\n");
3388 IDirect3D_Release(d3d
);
3392 memset(palette_entries
, 0, sizeof(palette_entries
));
3393 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
3394 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
3396 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
3398 IDirectDrawSurface
*surface
;
3399 DDSURFACEDESC surface_desc
;
3400 IDirect3DDevice
*device
;
3402 memset(&surface_desc
, 0, sizeof(surface_desc
));
3403 surface_desc
.dwSize
= sizeof(surface_desc
);
3404 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
3405 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
3406 if (test_data
[i
].pf
)
3408 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
3409 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
3411 if (test_data
[i
].caps_in
& DDSCAPS_ZBUFFER
)
3413 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
3414 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
3416 surface_desc
.dwWidth
= 640;
3417 surface_desc
.dwHeight
= 480;
3418 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
3419 ok(SUCCEEDED(hr
) || broken(test_data
[i
].create_may_fail
),
3420 "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
3421 i
, test_data
[i
].caps_in
, hr
);
3425 memset(&surface_desc
, 0, sizeof(surface_desc
));
3426 surface_desc
.dwSize
= sizeof(surface_desc
);
3427 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
3428 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
3429 ok(test_data
[i
].caps_out
== ~0U || surface_desc
.ddsCaps
.dwCaps
== test_data
[i
].caps_out
,
3430 "Test %u: Got unexpected caps %#x, expected %#x.\n",
3431 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
3433 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DHALDevice
, (void **)&device
);
3434 ok(hr
== test_data
[i
].create_device_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n",
3435 i
, hr
, test_data
[i
].create_device_hr
);
3436 if (hr
== DDERR_NOPALETTEATTACHED
)
3438 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
3439 ok(SUCCEEDED(hr
), "Test %u: Failed to set palette, hr %#x.\n", i
, hr
);
3440 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DHALDevice
, (void **)&device
);
3441 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
3442 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
3444 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
3448 refcount
= IDirect3DDevice_Release(device
);
3449 ok(refcount
== 1, "Test %u: Got unexpected refcount %u.\n", i
, refcount
);
3452 refcount
= IDirectDrawSurface_Release(surface
);
3453 ok(refcount
== 0, "Test %u: The surface was not properly freed, refcount %u.\n", i
, refcount
);
3456 IDirectDrawPalette_Release(palette
);
3457 IDirect3D_Release(d3d
);
3460 refcount
= IDirectDraw_Release(ddraw
);
3461 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
3462 DestroyWindow(window
);
3465 static void test_primary_caps(void)
3467 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
3468 IDirectDrawSurface
*surface
;
3469 DDSURFACEDESC surface_desc
;
3480 DWORD back_buffer_count
;
3488 DDSCAPS_PRIMARYSURFACE
,
3491 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
3495 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
3502 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
3505 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
3509 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
3516 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
3523 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
3530 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
3537 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
3544 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
3546 DDERR_NOEXCLUSIVEMODE
,
3550 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
3551 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
3557 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
3558 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
3561 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
3564 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
3565 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
3571 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
3572 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
3579 if (!(ddraw
= create_ddraw()))
3581 skip("Failed to create a ddraw object, skipping test.\n");
3585 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3586 0, 0, 640, 480, 0, 0, 0, 0);
3588 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
3590 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
3591 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3593 memset(&surface_desc
, 0, sizeof(surface_desc
));
3594 surface_desc
.dwSize
= sizeof(surface_desc
);
3595 surface_desc
.dwFlags
= DDSD_CAPS
;
3596 if (test_data
[i
].back_buffer_count
!= ~0u)
3597 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
3598 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
3599 surface_desc
.dwBackBufferCount
= test_data
[i
].back_buffer_count
;
3600 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
3601 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
3605 memset(&surface_desc
, 0, sizeof(surface_desc
));
3606 surface_desc
.dwSize
= sizeof(surface_desc
);
3607 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
3608 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
3609 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
3610 "Test %u: Got unexpected caps %#x, expected %#x.\n",
3611 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
3613 IDirectDrawSurface_Release(surface
);
3616 refcount
= IDirectDraw_Release(ddraw
);
3617 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
3618 DestroyWindow(window
);
3621 static void test_surface_lock(void)
3624 IDirect3D
*d3d
= NULL
;
3625 IDirectDrawSurface
*surface
;
3640 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
3641 "videomemory offscreenplain"
3644 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3645 "systemmemory offscreenplain"
3648 DDSCAPS_PRIMARYSURFACE
,
3652 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
3653 "videomemory texture"
3656 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
3657 "systemmemory texture"
3660 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
3669 if (!(ddraw
= create_ddraw()))
3671 skip("Failed to create a ddraw object, skipping test.\n");
3675 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3676 0, 0, 640, 480, 0, 0, 0, 0);
3677 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3678 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3680 if (FAILED(hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
)))
3682 skip("D3D interface is not available, skipping test.\n");
3686 hr
= IDirect3D_EnumDevices(d3d
, enum_z_fmt
, &z_depth
);
3687 if (FAILED(hr
) || !z_depth
)
3689 skip("No depth buffer formats available, skipping test.\n");
3693 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
3695 memset(&ddsd
, 0, sizeof(ddsd
)),
3696 ddsd
.dwSize
= sizeof(ddsd
);
3697 ddsd
.dwFlags
= DDSD_CAPS
;
3698 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
3700 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
3704 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
3706 ddsd
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
3707 U2(ddsd
).dwZBufferBitDepth
= z_depth
;
3709 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
3711 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3712 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
3714 memset(&ddsd
, 0, sizeof(ddsd
)),
3715 ddsd
.dwSize
= sizeof(ddsd
);
3716 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
3717 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
3720 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
3721 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
3724 IDirectDrawSurface_Release(surface
);
3730 IDirect3D_Release(d3d
);
3731 refcount
= IDirectDraw_Release(ddraw
);
3732 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
3733 DestroyWindow(window
);
3736 static void test_surface_discard(void)
3742 IDirectDrawSurface
*surface
, *primary
;
3751 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, TRUE
},
3752 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
3753 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, TRUE
},
3754 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
3758 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3759 0, 0, 640, 480, 0, 0, 0, 0);
3760 if (!(ddraw
= create_ddraw()))
3762 skip("Failed to create a ddraw object, skipping test.\n");
3763 DestroyWindow(window
);
3766 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3767 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3769 memset(&ddsd
, 0, sizeof(ddsd
));
3770 ddsd
.dwSize
= sizeof(ddsd
);
3771 ddsd
.dwFlags
= DDSD_CAPS
;
3772 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3773 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3775 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
3779 memset(&ddsd
, 0, sizeof(ddsd
));
3780 ddsd
.dwSize
= sizeof(ddsd
);
3781 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
3782 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
3785 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3788 skip("Failed to create surface, skipping.\n");
3792 memset(&ddsd
, 0, sizeof(ddsd
));
3793 ddsd
.dwSize
= sizeof(ddsd
);
3794 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
3795 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
3796 addr
= ddsd
.lpSurface
;
3797 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
3798 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
3800 memset(&ddsd
, 0, sizeof(ddsd
));
3801 ddsd
.dwSize
= sizeof(ddsd
);
3802 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
3803 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
3804 discarded
= ddsd
.lpSurface
!= addr
;
3805 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
3806 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
3808 hr
= IDirectDrawSurface_Blt(primary
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
3809 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
3811 memset(&ddsd
, 0, sizeof(ddsd
));
3812 ddsd
.dwSize
= sizeof(ddsd
);
3813 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
3814 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
3815 discarded
|= ddsd
.lpSurface
!= addr
;
3816 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
3817 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
3819 IDirectDrawSurface_Release(surface
);
3821 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
3822 * AMD r500, evergreen). Windows XP, at least on AMD r200, never changes the pointer. */
3823 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
3826 IDirectDrawSurface_Release(primary
);
3827 IDirectDraw_Release(ddraw
);
3828 DestroyWindow(window
);
3831 static void test_flip(void)
3833 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
3834 IDirectDrawSurface
*primary
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
3835 DDSCAPS caps
= {DDSCAPS_FLIP
};
3836 DDSURFACEDESC surface_desc
;
3837 BOOL sysmem_primary
;
3845 if (!(ddraw
= create_ddraw()))
3847 skip("Failed to create a ddraw object, skipping test.\n");
3851 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3852 0, 0, 640, 480, 0, 0, 0, 0);
3854 hr
= IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 32);
3855 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3856 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3857 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3859 memset(&surface_desc
, 0, sizeof(surface_desc
));
3860 surface_desc
.dwSize
= sizeof(surface_desc
);
3861 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
3862 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
3863 surface_desc
.dwBackBufferCount
= 3;
3864 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
3865 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
3867 memset(&surface_desc
, 0, sizeof(surface_desc
));
3868 surface_desc
.dwSize
= sizeof(surface_desc
);
3869 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
3870 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3871 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
)
3872 == (DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
),
3873 "Got unexpected caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
3874 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
3876 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &caps
, &backbuffer1
);
3877 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
3878 memset(&surface_desc
, 0, sizeof(surface_desc
));
3879 surface_desc
.dwSize
= sizeof(surface_desc
);
3880 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer1
, &surface_desc
);
3881 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3882 ok(!surface_desc
.dwBackBufferCount
, "Got unexpected back buffer count %u.\n", surface_desc
.dwBackBufferCount
);
3883 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == (DDSCAPS_FLIP
| DDSCAPS_COMPLEX
| DDSCAPS_BACKBUFFER
),
3884 "Got unexpected caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
3886 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
3887 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
3888 memset(&surface_desc
, 0, sizeof(surface_desc
));
3889 surface_desc
.dwSize
= sizeof(surface_desc
);
3890 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer2
, &surface_desc
);
3891 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3892 ok(!surface_desc
.dwBackBufferCount
, "Got unexpected back buffer count %u.\n", surface_desc
.dwBackBufferCount
);
3893 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == (DDSCAPS_FLIP
| DDSCAPS_COMPLEX
),
3894 "Got unexpected caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
3896 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
3897 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
3898 memset(&surface_desc
, 0, sizeof(surface_desc
));
3899 surface_desc
.dwSize
= sizeof(surface_desc
);
3900 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer3
, &surface_desc
);
3901 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3902 ok(!surface_desc
.dwBackBufferCount
, "Got unexpected back buffer count %u.\n", surface_desc
.dwBackBufferCount
);
3903 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == (DDSCAPS_FLIP
| DDSCAPS_COMPLEX
),
3904 "Got unexpected caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
3906 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
3907 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
3908 ok(surface
== primary
, "Got unexpected surface %p, expected %p.\n", surface
, primary
);
3909 IDirectDrawSurface_Release(surface
);
3911 memset(&surface_desc
, 0, sizeof(surface_desc
));
3912 surface_desc
.dwSize
= sizeof(surface_desc
);
3913 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
3914 surface_desc
.ddsCaps
.dwCaps
= 0;
3915 surface_desc
.dwWidth
= 640;
3916 surface_desc
.dwHeight
= 480;
3917 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
3918 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
3919 hr
= IDirectDrawSurface_Flip(primary
, surface
, DDFLIP_WAIT
);
3920 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
3921 IDirectDrawSurface_Release(surface
);
3923 hr
= IDirectDrawSurface_Flip(primary
, primary
, DDFLIP_WAIT
);
3924 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
3925 hr
= IDirectDrawSurface_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
3926 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
3927 hr
= IDirectDrawSurface_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
3928 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
3929 hr
= IDirectDrawSurface_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
3930 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
3932 memset(&fx
, 0, sizeof(fx
));
3933 fx
.dwSize
= sizeof(fx
);
3934 U5(fx
).dwFillColor
= 0xffff0000;
3935 hr
= IDirectDrawSurface_Blt(backbuffer1
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
3936 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
3937 U5(fx
).dwFillColor
= 0xff00ff00;
3938 hr
= IDirectDrawSurface_Blt(backbuffer2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
3939 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
3940 U5(fx
).dwFillColor
= 0xff0000ff;
3941 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
3942 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
3944 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
3945 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
3946 color
= get_surface_color(backbuffer1
, 320, 240);
3947 /* The testbot seems to just copy the contents of one surface to all the
3948 * others, instead of properly flipping. */
3949 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
3950 "Got unexpected color 0x%08x.\n", color
);
3951 color
= get_surface_color(backbuffer2
, 320, 240);
3952 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
3953 U5(fx
).dwFillColor
= 0xffff0000;
3954 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
3955 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
3957 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
3958 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
3959 color
= get_surface_color(backbuffer1
, 320, 240);
3960 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
3961 "Got unexpected color 0x%08x.\n", color
);
3962 color
= get_surface_color(backbuffer2
, 320, 240);
3963 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
3964 U5(fx
).dwFillColor
= 0xff00ff00;
3965 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
3966 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
3968 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
3969 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
3970 color
= get_surface_color(backbuffer1
, 320, 240);
3971 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
3972 "Got unexpected color 0x%08x.\n", color
);
3973 color
= get_surface_color(backbuffer2
, 320, 240);
3974 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
3975 U5(fx
).dwFillColor
= 0xff0000ff;
3976 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
3977 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
3979 hr
= IDirectDrawSurface_Flip(primary
, backbuffer1
, DDFLIP_WAIT
);
3980 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
3981 color
= get_surface_color(backbuffer2
, 320, 240);
3982 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
3983 "Got unexpected color 0x%08x.\n", color
);
3984 color
= get_surface_color(backbuffer3
, 320, 240);
3985 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
3986 U5(fx
).dwFillColor
= 0xffff0000;
3987 hr
= IDirectDrawSurface_Blt(backbuffer1
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
3988 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
3990 hr
= IDirectDrawSurface_Flip(primary
, backbuffer2
, DDFLIP_WAIT
);
3991 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
3992 color
= get_surface_color(backbuffer1
, 320, 240);
3993 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
3994 color
= get_surface_color(backbuffer3
, 320, 240);
3995 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
3996 "Got unexpected color 0x%08x.\n", color
);
3997 U5(fx
).dwFillColor
= 0xff00ff00;
3998 hr
= IDirectDrawSurface_Blt(backbuffer2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
3999 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4001 hr
= IDirectDrawSurface_Flip(primary
, backbuffer3
, DDFLIP_WAIT
);
4002 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
4003 color
= get_surface_color(backbuffer1
, 320, 240);
4004 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
4005 "Got unexpected color 0x%08x.\n", color
);
4006 color
= get_surface_color(backbuffer2
, 320, 240);
4007 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
4009 IDirectDrawSurface_Release(backbuffer3
);
4010 IDirectDrawSurface_Release(backbuffer2
);
4011 IDirectDrawSurface_Release(backbuffer1
);
4012 IDirectDrawSurface_Release(primary
);
4013 refcount
= IDirectDraw_Release(ddraw
);
4014 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4015 DestroyWindow(window
);
4018 static void test_sysmem_overlay(void)
4024 IDirectDrawSurface
*surface
;
4027 if (!(ddraw
= create_ddraw()))
4029 skip("Failed to create a ddraw object, skipping test.\n");
4033 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4034 0, 0, 640, 480, 0, 0, 0, 0);
4036 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4037 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4039 memset(&ddsd
, 0, sizeof(ddsd
));
4040 ddsd
.dwSize
= sizeof(ddsd
);
4041 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
4044 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
4045 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
4046 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4047 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
4048 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
4049 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
4050 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
4051 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4052 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#x.\n", hr
);
4054 ref
= IDirectDraw_Release(ddraw
);
4055 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
4056 DestroyWindow(window
);
4059 static void test_primary_palette(void)
4061 DDSCAPS surface_caps
= {DDSCAPS_FLIP
};
4062 IDirectDrawSurface
*primary
, *backbuffer
;
4063 PALETTEENTRY palette_entries
[256];
4064 IDirectDrawPalette
*palette
, *tmp
;
4065 DDSURFACEDESC surface_desc
;
4072 if (!(ddraw
= create_ddraw()))
4074 skip("Failed to create a ddraw object, skipping test.\n");
4078 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4079 0, 0, 640, 480, 0, 0, 0, 0);
4080 hr
= IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 8);
4081 if (hr
== E_NOTIMPL
)
4083 win_skip("changing display mode is not supported (8bpp)\n");
4084 IDirectDraw_Release(ddraw
);
4085 DestroyWindow(window
);
4088 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
4089 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4090 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4092 memset(&surface_desc
, 0, sizeof(surface_desc
));
4093 surface_desc
.dwSize
= sizeof(surface_desc
);
4094 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
4095 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
4096 surface_desc
.dwBackBufferCount
= 1;
4097 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
4098 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4099 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
4100 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
4102 memset(palette_entries
, 0, sizeof(palette_entries
));
4103 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
4104 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
4105 refcount
= get_refcount((IUnknown
*)palette
);
4106 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
4108 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
4109 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
4110 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
4112 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
4113 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
4114 refcount
= get_refcount((IUnknown
*)palette
);
4115 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
4117 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
4118 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
4119 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
4120 "Got unexpected palette caps %#x.\n", palette_caps
);
4122 hr
= IDirectDrawSurface_SetPalette(primary
, NULL
);
4123 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
4124 refcount
= get_refcount((IUnknown
*)palette
);
4125 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
4127 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
4128 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
4129 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
4131 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
4132 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
4133 refcount
= get_refcount((IUnknown
*)palette
);
4134 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
4136 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
4137 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
4138 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
4139 IDirectDrawPalette_Release(tmp
);
4140 hr
= IDirectDrawSurface_GetPalette(backbuffer
, &tmp
);
4141 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
4143 refcount
= IDirectDrawPalette_Release(palette
);
4144 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
4145 refcount
= IDirectDrawPalette_Release(palette
);
4146 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
4148 /* Note that this only seems to work when the palette is attached to the
4149 * primary surface. When attached to a regular surface, attempting to get
4150 * the palette here will cause an access violation. */
4151 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
4152 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
4154 refcount
= IDirectDrawSurface_Release(backbuffer
);
4155 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
4156 refcount
= IDirectDrawSurface_Release(primary
);
4157 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
4158 refcount
= IDirectDraw_Release(ddraw
);
4159 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
4160 DestroyWindow(window
);
4163 static HRESULT WINAPI
surface_counter(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
4165 UINT
*surface_count
= context
;
4168 IDirectDrawSurface_Release(surface
);
4170 return DDENUMRET_OK
;
4173 static void test_surface_attachment(void)
4175 IDirectDrawSurface
*surface1
, *surface2
, *surface3
, *surface4
;
4176 DDSCAPS caps
= {DDSCAPS_TEXTURE
};
4177 DDSURFACEDESC surface_desc
;
4184 if (!(ddraw
= create_ddraw()))
4186 skip("Failed to create a ddraw object, skipping test.\n");
4190 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4191 0, 0, 640, 480, 0, 0, 0, 0);
4192 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4193 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4195 memset(&surface_desc
, 0, sizeof(surface_desc
));
4196 surface_desc
.dwSize
= sizeof(surface_desc
);
4197 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
4198 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
4199 U2(surface_desc
).dwMipMapCount
= 3;
4200 surface_desc
.dwWidth
= 128;
4201 surface_desc
.dwHeight
= 128;
4202 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
4203 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4205 hr
= IDirectDrawSurface_GetAttachedSurface(surface1
, &caps
, &surface2
);
4206 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
4207 hr
= IDirectDrawSurface_GetAttachedSurface(surface2
, &caps
, &surface3
);
4208 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
4209 hr
= IDirectDrawSurface_GetAttachedSurface(surface3
, &caps
, &surface4
);
4210 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
4213 IDirectDrawSurface_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
4214 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
4216 IDirectDrawSurface_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
4217 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
4219 IDirectDrawSurface_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
4220 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
4222 memset(&surface_desc
, 0, sizeof(surface_desc
));
4223 surface_desc
.dwSize
= sizeof(surface_desc
);
4224 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4225 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
4226 surface_desc
.dwWidth
= 16;
4227 surface_desc
.dwHeight
= 16;
4228 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
4229 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4231 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
4232 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4233 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
4234 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4235 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
4236 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4237 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
4238 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4239 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
4240 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4241 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
4242 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4244 IDirectDrawSurface_Release(surface4
);
4246 memset(&surface_desc
, 0, sizeof(surface_desc
));
4247 surface_desc
.dwSize
= sizeof(surface_desc
);
4248 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4249 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
4250 surface_desc
.dwWidth
= 16;
4251 surface_desc
.dwHeight
= 16;
4252 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
4253 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4255 if (SUCCEEDED(hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
)))
4257 skip("Running on refrast, skipping some tests.\n");
4258 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface4
);
4259 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
4263 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4264 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
4265 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4266 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
4267 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4268 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
4269 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4270 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
4271 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4272 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
4273 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4276 IDirectDrawSurface_Release(surface4
);
4277 IDirectDrawSurface_Release(surface3
);
4278 IDirectDrawSurface_Release(surface2
);
4279 IDirectDrawSurface_Release(surface1
);
4281 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4282 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4284 /* Try a single primary and two offscreen plain surfaces. */
4285 memset(&surface_desc
, 0, sizeof(surface_desc
));
4286 surface_desc
.dwSize
= sizeof(surface_desc
);
4287 surface_desc
.dwFlags
= DDSD_CAPS
;
4288 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4289 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
4290 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4292 memset(&surface_desc
, 0, sizeof(surface_desc
));
4293 surface_desc
.dwSize
= sizeof(surface_desc
);
4294 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4295 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
4296 surface_desc
.dwWidth
= GetSystemMetrics(SM_CXSCREEN
);
4297 surface_desc
.dwHeight
= GetSystemMetrics(SM_CYSCREEN
);
4298 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
4299 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4301 memset(&surface_desc
, 0, sizeof(surface_desc
));
4302 surface_desc
.dwSize
= sizeof(surface_desc
);
4303 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4304 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
4305 surface_desc
.dwWidth
= GetSystemMetrics(SM_CXSCREEN
);
4306 surface_desc
.dwHeight
= GetSystemMetrics(SM_CYSCREEN
);
4307 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
4308 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4310 /* This one has a different size. */
4311 memset(&surface_desc
, 0, sizeof(surface_desc
));
4312 surface_desc
.dwSize
= sizeof(surface_desc
);
4313 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4314 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
4315 surface_desc
.dwWidth
= 128;
4316 surface_desc
.dwHeight
= 128;
4317 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
4318 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4320 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
4321 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
4322 /* Try the reverse without detaching first. */
4323 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
4324 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
4325 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
4326 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
4328 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
4329 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
4330 /* Try to detach reversed. */
4331 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
4332 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4333 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface1
);
4334 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
4336 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface3
);
4337 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
4338 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface3
);
4339 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
4341 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
4342 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4343 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
4344 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4346 IDirectDrawSurface_Release(surface4
);
4347 IDirectDrawSurface_Release(surface3
);
4348 IDirectDrawSurface_Release(surface2
);
4349 IDirectDrawSurface_Release(surface1
);
4351 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
4352 memset(&surface_desc
, 0, sizeof(surface_desc
));
4353 surface_desc
.dwSize
= sizeof(surface_desc
);
4354 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
4355 surface_desc
.dwWidth
= 64;
4356 surface_desc
.dwHeight
= 64;
4357 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
4358 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
4359 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
4360 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
4361 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
4362 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
4363 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
4364 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
4365 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4366 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
4367 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4369 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
4370 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
4371 U1(surface_desc
.ddpfPixelFormat
).dwZBufferBitDepth
= 16;
4372 U3(surface_desc
.ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
4373 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
4374 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4376 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
4377 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
4378 refcount
= get_refcount((IUnknown
*)surface2
);
4379 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
4380 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
4381 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
4383 /* Attaching while already attached to other surface. */
4384 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface2
);
4385 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
4386 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface3
, 0, surface2
);
4387 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
4388 IDirectDrawSurface_Release(surface3
);
4390 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
4391 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
4392 refcount
= get_refcount((IUnknown
*)surface2
);
4393 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
4395 /* Automatic detachment on release. */
4396 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
4397 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
4398 refcount
= get_refcount((IUnknown
*)surface2
);
4399 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
4400 refcount
= IDirectDrawSurface_Release(surface1
);
4401 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
4402 refcount
= IDirectDrawSurface_Release(surface2
);
4403 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
4404 refcount
= IDirectDraw_Release(ddraw
);
4405 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
4406 DestroyWindow(window
);
4409 static void test_pixel_format(void)
4411 HWND window
, window2
= NULL
;
4412 HDC hdc
, hdc2
= NULL
;
4414 int format
, test_format
;
4415 PIXELFORMATDESCRIPTOR pfd
;
4416 IDirectDraw
*ddraw
= NULL
;
4417 IDirectDrawClipper
*clipper
= NULL
;
4419 IDirectDrawSurface
*primary
= NULL
;
4423 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4424 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
4427 skip("Failed to create window\n");
4431 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4432 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
4434 hdc
= GetDC(window
);
4437 skip("Failed to get DC\n");
4442 hdc2
= GetDC(window2
);
4444 gl
= LoadLibraryA("opengl32.dll");
4445 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
4447 format
= GetPixelFormat(hdc
);
4448 ok(format
== 0, "new window has pixel format %d\n", format
);
4450 ZeroMemory(&pfd
, sizeof(pfd
));
4451 pfd
.nSize
= sizeof(pfd
);
4453 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
4454 pfd
.iPixelType
= PFD_TYPE_RGBA
;
4455 pfd
.iLayerType
= PFD_MAIN_PLANE
;
4456 format
= ChoosePixelFormat(hdc
, &pfd
);
4459 skip("no pixel format available\n");
4463 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
4465 skip("failed to set pixel format\n");
4469 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
4471 skip("failed to set pixel format on second window\n");
4474 ReleaseDC(window2
, hdc2
);
4479 ddraw
= create_ddraw();
4482 skip("Failed to create ddraw object\n");
4486 test_format
= GetPixelFormat(hdc
);
4487 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
4489 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4492 skip("Failed to set cooperative level, hr %#x.\n", hr
);
4496 test_format
= GetPixelFormat(hdc
);
4497 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
4501 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
4502 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
4503 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
4504 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
4506 test_format
= GetPixelFormat(hdc
);
4507 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
4509 test_format
= GetPixelFormat(hdc2
);
4510 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
4513 memset(&ddsd
, 0, sizeof(ddsd
));
4514 ddsd
.dwSize
= sizeof(ddsd
);
4515 ddsd
.dwFlags
= DDSD_CAPS
;
4516 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4518 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
4519 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
4521 test_format
= GetPixelFormat(hdc
);
4522 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
4526 test_format
= GetPixelFormat(hdc2
);
4527 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
4532 hr
= IDirectDrawSurface_SetClipper(primary
, clipper
);
4533 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
4535 test_format
= GetPixelFormat(hdc
);
4536 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
4538 test_format
= GetPixelFormat(hdc2
);
4539 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
4542 memset(&fx
, 0, sizeof(fx
));
4543 fx
.dwSize
= sizeof(fx
);
4544 hr
= IDirectDrawSurface_Blt(primary
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4545 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
4547 test_format
= GetPixelFormat(hdc
);
4548 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
4552 test_format
= GetPixelFormat(hdc2
);
4553 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
4557 if (primary
) IDirectDrawSurface_Release(primary
);
4558 if (clipper
) IDirectDrawClipper_Release(clipper
);
4559 if (ddraw
) IDirectDraw_Release(ddraw
);
4560 if (gl
) FreeLibrary(gl
);
4561 if (hdc
) ReleaseDC(window
, hdc
);
4562 if (hdc2
) ReleaseDC(window2
, hdc2
);
4563 if (window
) DestroyWindow(window
);
4564 if (window2
) DestroyWindow(window2
);
4569 test_coop_level_create_device_window();
4571 test_coop_level_d3d_state();
4572 test_surface_interface_mismatch();
4573 test_coop_level_threaded();
4582 test_window_style();
4583 test_redundant_mode_set();
4584 test_coop_level_mode_set();
4585 test_coop_level_mode_set_multi();
4587 test_coop_level_surf_create();
4588 test_coop_level_multi_window();
4589 test_clear_rect_count();
4590 test_coop_level_activateapp();
4591 test_unsupported_formats();
4593 test_primary_caps();
4594 test_surface_lock();
4595 test_surface_discard();
4597 test_sysmem_overlay();
4598 test_primary_palette();
4599 test_surface_attachment();
4600 test_pixel_format();