2 * Copyright 2011-2014 Henri Verbeet for CodeWeavers
3 * Copyright 2012-2014 Stefan Dösinger for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/test.h"
24 struct create_window_thread_param
27 HANDLE window_created
;
28 HANDLE destroy_window
;
32 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
34 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
36 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
38 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
40 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
44 static DWORD WINAPI
create_window_thread_proc(void *param
)
46 struct create_window_thread_param
*p
= param
;
50 p
->window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
51 0, 0, 640, 480, 0, 0, 0, 0);
52 ret
= SetEvent(p
->window_created
);
53 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
59 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
60 DispatchMessageA(&msg
);
61 res
= WaitForSingleObject(p
->destroy_window
, 100);
62 if (res
== WAIT_OBJECT_0
)
64 if (res
!= WAIT_TIMEOUT
)
66 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
71 DestroyWindow(p
->window
);
76 static void create_window_thread(struct create_window_thread_param
*p
)
80 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
81 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
82 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
83 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
84 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
85 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
86 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
87 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
90 static void destroy_window_thread(struct create_window_thread_param
*p
)
92 SetEvent(p
->destroy_window
);
93 WaitForSingleObject(p
->thread
, INFINITE
);
94 CloseHandle(p
->destroy_window
);
95 CloseHandle(p
->window_created
);
96 CloseHandle(p
->thread
);
99 static IDirectDrawSurface
*get_depth_stencil(IDirect3DDevice2
*device
)
101 IDirectDrawSurface
*rt
, *ret
;
102 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
105 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
106 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
107 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ret
);
108 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
109 IDirectDrawSurface_Release(rt
);
113 static HRESULT
set_display_mode(IDirectDraw2
*ddraw
, DWORD width
, DWORD height
)
115 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
117 return IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0);
120 static D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
122 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
123 DDSURFACEDESC surface_desc
;
127 memset(&surface_desc
, 0, sizeof(surface_desc
));
128 surface_desc
.dwSize
= sizeof(surface_desc
);
130 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
131 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
135 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
137 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
138 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
143 static DWORD
get_device_z_depth(IDirect3DDevice2
*device
)
145 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
146 IDirectDrawSurface
*ds
, *rt
;
150 if (FAILED(IDirect3DDevice2_GetRenderTarget(device
, &rt
)))
153 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ds
);
154 IDirectDrawSurface_Release(rt
);
158 desc
.dwSize
= sizeof(desc
);
159 hr
= IDirectDrawSurface_GetSurfaceDesc(ds
, &desc
);
160 IDirectDrawSurface_Release(ds
);
164 return U2(desc
).dwZBufferBitDepth
;
167 static IDirectDraw2
*create_ddraw(void)
169 IDirectDraw2
*ddraw2
;
173 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
176 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw2
);
177 IDirectDraw_Release(ddraw1
);
184 static IDirect3DDevice2
*create_device(IDirectDraw2
*ddraw
, HWND window
, DWORD coop_level
)
186 static const DWORD z_depths
[] = {32, 24, 16};
187 IDirectDrawSurface
*surface
, *ds
;
188 IDirect3DDevice2
*device
= NULL
;
189 DDSURFACEDESC surface_desc
;
194 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, coop_level
);
195 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
197 memset(&surface_desc
, 0, sizeof(surface_desc
));
198 surface_desc
.dwSize
= sizeof(surface_desc
);
199 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
200 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
201 surface_desc
.dwWidth
= 640;
202 surface_desc
.dwHeight
= 480;
204 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
205 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
207 if (coop_level
& DDSCL_NORMAL
)
209 IDirectDrawClipper
*clipper
;
211 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
212 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
213 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
214 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
215 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
216 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
217 IDirectDrawClipper_Release(clipper
);
220 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
223 IDirectDrawSurface_Release(surface
);
227 /* We used to use EnumDevices() for this, but it seems
228 * D3DDEVICEDESC.dwDeviceZBufferBitDepth only has a very casual
229 * relationship with reality. */
230 for (i
= 0; i
< sizeof(z_depths
) / sizeof(*z_depths
); ++i
)
232 memset(&surface_desc
, 0, sizeof(surface_desc
));
233 surface_desc
.dwSize
= sizeof(surface_desc
);
234 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
235 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
236 U2(surface_desc
).dwZBufferBitDepth
= z_depths
[i
];
237 surface_desc
.dwWidth
= 640;
238 surface_desc
.dwHeight
= 480;
239 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
)))
242 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
243 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
244 IDirectDrawSurface_Release(ds
);
248 if (SUCCEEDED(IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
)))
251 IDirectDrawSurface_DeleteAttachedSurface(surface
, 0, ds
);
254 IDirect3D2_Release(d3d
);
255 IDirectDrawSurface_Release(surface
);
259 static IDirect3DViewport2
*create_viewport(IDirect3DDevice2
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
261 IDirect3DViewport2
*viewport
;
266 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
267 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
268 hr
= IDirect3D2_CreateViewport(d3d
, &viewport
, NULL
);
269 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
270 hr
= IDirect3DDevice2_AddViewport(device
, viewport
);
271 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
272 memset(&vp
, 0, sizeof(vp
));
273 vp
.dwSize
= sizeof(vp
);
280 vp
.dvClipWidth
= 2.0f
;
281 vp
.dvClipHeight
= 2.0f
;
284 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp
);
285 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
286 IDirect3D2_Release(d3d
);
291 static void viewport_set_background(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
,
292 IDirect3DMaterial2
*material
)
294 D3DMATERIALHANDLE material_handle
;
297 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &material_handle
);
298 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
299 hr
= IDirect3DViewport2_SetBackground(viewport
, material_handle
);
300 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
303 static void destroy_viewport(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
)
307 hr
= IDirect3DDevice2_DeleteViewport(device
, viewport
);
308 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
309 IDirect3DViewport2_Release(viewport
);
312 static IDirect3DMaterial2
*create_material(IDirect3DDevice2
*device
, D3DMATERIAL
*mat
)
314 IDirect3DMaterial2
*material
;
318 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
319 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
320 hr
= IDirect3D2_CreateMaterial(d3d
, &material
, NULL
);
321 ok(SUCCEEDED(hr
), "Failed to create material, hr %#x.\n", hr
);
322 hr
= IDirect3DMaterial2_SetMaterial(material
, mat
);
323 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
324 IDirect3D2_Release(d3d
);
329 static IDirect3DMaterial2
*create_diffuse_material(IDirect3DDevice2
*device
, float r
, float g
, float b
, float a
)
333 memset(&mat
, 0, sizeof(mat
));
334 mat
.dwSize
= sizeof(mat
);
335 U1(U(mat
).diffuse
).r
= r
;
336 U2(U(mat
).diffuse
).g
= g
;
337 U3(U(mat
).diffuse
).b
= b
;
338 U4(U(mat
).diffuse
).a
= a
;
340 return create_material(device
, &mat
);
343 static IDirect3DMaterial2
*create_emissive_material(IDirect3DDevice2
*device
, float r
, float g
, float b
, float a
)
347 memset(&mat
, 0, sizeof(mat
));
348 mat
.dwSize
= sizeof(mat
);
349 U1(U3(mat
).emissive
).r
= r
;
350 U2(U3(mat
).emissive
).g
= g
;
351 U3(U3(mat
).emissive
).b
= b
;
352 U4(U3(mat
).emissive
).a
= a
;
354 return create_material(device
, &mat
);
357 static void destroy_material(IDirect3DMaterial2
*material
)
359 IDirect3DMaterial2_Release(material
);
362 static const UINT
*expect_messages
;
364 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
366 if (expect_messages
&& message
== *expect_messages
)
369 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
372 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
373 * interface. This prevents subsequent SetCooperativeLevel() calls on a
374 * different window from failing with DDERR_HWNDALREADYSET. */
375 static void fix_wndproc(HWND window
, LONG_PTR proc
)
380 if (!(ddraw
= create_ddraw()))
383 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
384 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
385 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
386 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
387 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
389 IDirectDraw2_Release(ddraw
);
392 static HRESULT CALLBACK
restore_callback(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
394 HRESULT hr
= IDirectDrawSurface_Restore(surface
);
395 ok(SUCCEEDED(hr
) || hr
== DDERR_IMPLICITLYCREATED
, "Failed to restore surface, hr %#x.\n", hr
);
396 IDirectDrawSurface_Release(surface
);
401 static HRESULT
restore_surfaces(IDirectDraw2
*ddraw
)
403 return IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
,
404 NULL
, NULL
, restore_callback
);
407 static void test_coop_level_create_device_window(void)
409 HWND focus_window
, device_window
;
413 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
414 0, 0, 640, 480, 0, 0, 0, 0);
415 ddraw
= create_ddraw();
416 ok(!!ddraw
, "Failed to create a ddraw object.\n");
418 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
419 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
420 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
421 ok(!device_window
, "Unexpected device window found.\n");
422 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
423 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
424 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
425 ok(!device_window
, "Unexpected device window found.\n");
426 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
427 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
428 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
429 ok(!device_window
, "Unexpected device window found.\n");
430 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
431 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
432 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
433 ok(!device_window
, "Unexpected device window found.\n");
434 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
435 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
436 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
437 ok(!device_window
, "Unexpected device window found.\n");
439 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
440 if (broken(hr
== DDERR_INVALIDPARAMS
))
442 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
443 IDirectDraw2_Release(ddraw
);
444 DestroyWindow(focus_window
);
448 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
449 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
450 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
451 ok(!device_window
, "Unexpected device window found.\n");
452 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
453 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
454 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
455 ok(!device_window
, "Unexpected device window found.\n");
457 hr
= IDirectDraw2_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
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
462 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
463 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
464 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
465 ok(!!device_window
, "Device window not found.\n");
467 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
468 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
469 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
470 ok(!device_window
, "Unexpected device window found.\n");
471 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
472 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
473 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
474 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
475 ok(!!device_window
, "Device window not found.\n");
477 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
478 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
479 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
480 ok(!device_window
, "Unexpected device window found.\n");
481 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
482 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
483 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
484 ok(!device_window
, "Unexpected device window found.\n");
485 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
486 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
487 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
488 ok(!device_window
, "Unexpected device window found.\n");
489 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
490 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
491 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
492 ok(!!device_window
, "Device window not found.\n");
494 IDirectDraw2_Release(ddraw
);
495 DestroyWindow(focus_window
);
498 static void test_clipper_blt(void)
500 IDirectDrawSurface
*src_surface
, *dst_surface
;
501 RECT client_rect
, src_rect
;
502 IDirectDrawClipper
*clipper
;
503 DDSURFACEDESC surface_desc
;
504 unsigned int i
, j
, x
, y
;
515 static const DWORD src_data
[] =
517 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
518 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
519 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
521 static const D3DCOLOR expected1
[] =
523 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
524 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
525 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
526 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
528 /* Nvidia on Windows seems to have an off-by-one error
529 * when processing source rectangles. Our left = 1 and
530 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
531 * read as well, but only for the edge pixels on the
532 * output image. The bug happens on the y axis as well,
533 * but we only read one row there, and all source rows
534 * contain the same data. This bug is not dependent on
535 * the presence of a clipper. */
536 static const D3DCOLOR expected1_broken
[] =
538 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
539 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
540 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
541 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
543 static const D3DCOLOR expected2
[] =
545 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
546 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
547 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
548 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
551 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
552 10, 10, 640, 480, 0, 0, 0, 0);
553 ShowWindow(window
, SW_SHOW
);
554 ddraw
= create_ddraw();
555 ok(!!ddraw
, "Failed to create a ddraw object.\n");
557 ret
= GetClientRect(window
, &client_rect
);
558 ok(ret
, "Failed to get client rect.\n");
559 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
560 ok(ret
, "Failed to map client rect.\n");
562 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
563 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
565 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
566 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
567 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
568 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
569 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
570 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
571 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
572 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
573 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
574 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
575 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
576 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
577 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
578 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
579 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
580 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
581 rgn_data
->rdh
.rcBound
.left
, rgn_data
->rdh
.rcBound
.top
,
582 rgn_data
->rdh
.rcBound
.right
, rgn_data
->rdh
.rcBound
.bottom
,
583 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
584 HeapFree(GetProcessHeap(), 0, rgn_data
);
586 r1
= CreateRectRgn(0, 0, 320, 240);
587 ok(!!r1
, "Failed to create region.\n");
588 r2
= CreateRectRgn(320, 240, 640, 480);
589 ok(!!r2
, "Failed to create region.\n");
590 CombineRgn(r1
, r1
, r2
, RGN_OR
);
591 ret
= GetRegionData(r1
, 0, NULL
);
592 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
593 ret
= GetRegionData(r1
, ret
, rgn_data
);
594 ok(!!ret
, "Failed to get region data.\n");
599 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
600 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
601 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
602 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
603 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
604 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
606 HeapFree(GetProcessHeap(), 0, rgn_data
);
608 memset(&surface_desc
, 0, sizeof(surface_desc
));
609 surface_desc
.dwSize
= sizeof(surface_desc
);
610 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
611 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
612 surface_desc
.dwWidth
= 640;
613 surface_desc
.dwHeight
= 480;
614 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
615 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
616 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
617 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
618 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
619 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
621 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
622 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
623 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
624 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
626 memset(&fx
, 0, sizeof(fx
));
627 fx
.dwSize
= sizeof(fx
);
628 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
629 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
630 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
631 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
633 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
634 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
635 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
636 ptr
= surface_desc
.lpSurface
;
637 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
638 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
639 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
640 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
641 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
643 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
644 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
646 SetRect(&src_rect
, 1, 1, 5, 2);
647 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
648 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
649 for (i
= 0; i
< 4; ++i
)
651 for (j
= 0; j
< 4; ++j
)
653 x
= 80 * ((2 * j
) + 1);
654 y
= 60 * ((2 * i
) + 1);
655 color
= get_surface_color(dst_surface
, x
, y
);
656 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
657 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
658 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
662 U5(fx
).dwFillColor
= 0xff0000ff;
663 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
664 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
665 for (i
= 0; i
< 4; ++i
)
667 for (j
= 0; j
< 4; ++j
)
669 x
= 80 * ((2 * j
) + 1);
670 y
= 60 * ((2 * i
) + 1);
671 color
= get_surface_color(dst_surface
, x
, y
);
672 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
673 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
677 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
678 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#x.\n", hr
);
680 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
681 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
682 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
683 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
684 DestroyWindow(window
);
685 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
686 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
687 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
688 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
689 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
690 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
691 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
692 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
693 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
694 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
695 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
696 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
698 IDirectDrawSurface_Release(dst_surface
);
699 IDirectDrawSurface_Release(src_surface
);
700 IDirectDrawClipper_Release(clipper
);
701 IDirectDraw2_Release(ddraw
);
704 static void test_coop_level_d3d_state(void)
706 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
707 IDirectDrawSurface
*rt
, *surface
;
708 IDirect3DMaterial2
*background
;
709 IDirect3DViewport2
*viewport
;
710 IDirect3DDevice2
*device
;
711 D3DMATERIAL material
;
718 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
719 0, 0, 640, 480, 0, 0, 0, 0);
720 ddraw
= create_ddraw();
721 ok(!!ddraw
, "Failed to create a ddraw object.\n");
722 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
724 skip("Failed to create a 3D device, skipping test.\n");
725 IDirectDraw2_Release(ddraw
);
726 DestroyWindow(window
);
730 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
731 viewport
= create_viewport(device
, 0, 0, 640, 480);
732 viewport_set_background(device
, viewport
, background
);
734 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
735 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
736 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
737 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
738 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
739 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
740 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
741 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
742 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
743 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
744 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
745 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
746 color
= get_surface_color(rt
, 320, 240);
747 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
749 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
750 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
751 hr
= IDirectDrawSurface_IsLost(rt
);
752 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
753 hr
= restore_surfaces(ddraw
);
754 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
756 memset(&material
, 0, sizeof(material
));
757 material
.dwSize
= sizeof(material
);
758 U1(U(material
).diffuse
).r
= 0.0f
;
759 U2(U(material
).diffuse
).g
= 1.0f
;
760 U3(U(material
).diffuse
).b
= 0.0f
;
761 U4(U(material
).diffuse
).a
= 1.0f
;
762 hr
= IDirect3DMaterial2_SetMaterial(background
, &material
);
763 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
765 hr
= IDirect3DDevice2_GetRenderTarget(device
, &surface
);
766 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
767 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
768 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
769 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
770 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
771 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
772 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
773 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
774 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
775 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
776 color
= get_surface_color(rt
, 320, 240);
777 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
779 destroy_viewport(device
, viewport
);
780 destroy_material(background
);
781 IDirectDrawSurface_Release(surface
);
782 IDirectDrawSurface_Release(rt
);
783 IDirect3DDevice2_Release(device
);
784 IDirectDraw2_Release(ddraw
);
785 DestroyWindow(window
);
788 static void test_surface_interface_mismatch(void)
790 IDirectDraw2
*ddraw
= NULL
;
791 IDirect3D2
*d3d
= NULL
;
792 IDirectDrawSurface
*surface
= NULL
, *ds
;
793 IDirectDrawSurface3
*surface3
= NULL
;
794 IDirect3DDevice2
*device
= NULL
;
795 IDirect3DViewport2
*viewport
= NULL
;
796 IDirect3DMaterial2
*background
= NULL
;
797 DDSURFACEDESC surface_desc
;
803 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
805 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
806 0, 0, 640, 480, 0, 0, 0, 0);
807 ddraw
= create_ddraw();
808 ok(!!ddraw
, "Failed to create a ddraw object.\n");
809 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
811 skip("Failed to create a 3D device, skipping test.\n");
812 IDirectDraw2_Release(ddraw
);
813 DestroyWindow(window
);
816 z_depth
= get_device_z_depth(device
);
817 ok(!!z_depth
, "Failed to get device z depth.\n");
818 IDirect3DDevice2_Release(device
);
821 memset(&surface_desc
, 0, sizeof(surface_desc
));
822 surface_desc
.dwSize
= sizeof(surface_desc
);
823 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
824 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
825 surface_desc
.dwWidth
= 640;
826 surface_desc
.dwHeight
= 480;
828 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
829 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
831 hr
= IDirectDrawSurface2_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
834 skip("Failed to get the IDirectDrawSurface3 interface, skipping test.\n");
838 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
840 skip("D3D interface is not available, skipping test.\n");
844 memset(&surface_desc
, 0, sizeof(surface_desc
));
845 surface_desc
.dwSize
= sizeof(surface_desc
);
846 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
847 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
848 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
849 surface_desc
.dwWidth
= 640;
850 surface_desc
.dwHeight
= 480;
851 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
852 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
856 /* Using a different surface interface version still works */
857 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
858 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
859 refcount
= IDirectDrawSurface_Release(ds
);
860 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
865 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface
*)surface3
, &device
);
866 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
870 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
871 viewport
= create_viewport(device
, 0, 0, 640, 480);
872 viewport_set_background(device
, viewport
, background
);
874 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
875 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
876 color
= get_surface_color(surface
, 320, 240);
877 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
881 destroy_viewport(device
, viewport
);
883 destroy_material(background
);
884 if (surface3
) IDirectDrawSurface3_Release(surface3
);
885 if (surface
) IDirectDrawSurface_Release(surface
);
886 if (device
) IDirect3DDevice2_Release(device
);
887 if (d3d
) IDirect3D2_Release(d3d
);
888 if (ddraw
) IDirectDraw2_Release(ddraw
);
889 DestroyWindow(window
);
892 static void test_coop_level_threaded(void)
894 struct create_window_thread_param p
;
898 ddraw
= create_ddraw();
899 ok(!!ddraw
, "Failed to create a ddraw object.\n");
900 create_window_thread(&p
);
902 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
903 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
905 IDirectDraw2_Release(ddraw
);
906 destroy_window_thread(&p
);
909 static void test_depth_blit(void)
911 static D3DLVERTEX quad1
[] =
913 {{-1.0}, { 1.0}, {0.50f
}, 0, {0xff00ff00}},
914 {{ 1.0}, { 1.0}, {0.50f
}, 0, {0xff00ff00}},
915 {{-1.0}, {-1.0}, {0.50f
}, 0, {0xff00ff00}},
916 {{ 1.0}, {-1.0}, {0.50f
}, 0, {0xff00ff00}},
918 static const D3DCOLOR expected_colors
[4][4] =
920 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
921 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
922 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
923 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
925 DDSURFACEDESC ddsd_new
, ddsd_existing
;
927 IDirect3DDevice2
*device
;
928 IDirectDrawSurface
*ds1
, *ds2
, *ds3
, *rt
;
929 IDirect3DViewport2
*viewport
;
930 RECT src_rect
, dst_rect
;
938 IDirect3DMaterial2
*background
;
940 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
941 0, 0, 640, 480, 0, 0, 0, 0);
942 ddraw
= create_ddraw();
943 ok(!!ddraw
, "Failed to create a ddraw object.\n");
944 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
946 skip("Failed to create a 3D device, skipping test.\n");
947 IDirectDraw2_Release(ddraw
);
948 DestroyWindow(window
);
952 ds1
= get_depth_stencil(device
);
954 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
955 ddsd_new
.dwSize
= sizeof(ddsd_new
);
956 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
957 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
958 hr
= IDirectDrawSurface_GetSurfaceDesc(ds1
, &ddsd_existing
);
959 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
960 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
961 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
962 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
963 ddsd_new
.ddpfPixelFormat
= ddsd_existing
.ddpfPixelFormat
;
964 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
965 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
966 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
967 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
969 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
970 viewport
= create_viewport(device
, 0, 0, ddsd_existing
.dwWidth
, ddsd_existing
.dwHeight
);
971 viewport_set_background(device
, viewport
, background
);
972 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
973 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
975 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
976 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
977 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
978 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
980 U1(d3drect
).x1
= U2(d3drect
).y1
= 0;
981 U3(d3drect
).x2
= ddsd_existing
.dwWidth
; U4(d3drect
).y2
= ddsd_existing
.dwHeight
;
982 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
);
983 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
986 SetRect(&src_rect
, 0, 0, 320, 240);
987 SetRect(&dst_rect
, 0, 0, 320, 240);
988 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
989 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
990 /* Different locations. */
991 SetRect(&src_rect
, 0, 0, 320, 240);
992 SetRect(&dst_rect
, 320, 240, 640, 480);
993 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
994 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
996 SetRect(&src_rect
, 0, 0, 320, 240);
997 SetRect(&dst_rect
, 0, 0, 640, 480);
998 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
999 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1001 SetRect(&src_rect
, 0, 480, 640, 0);
1002 SetRect(&dst_rect
, 0, 0, 640, 480);
1003 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1004 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1005 SetRect(&src_rect
, 0, 0, 640, 480);
1006 SetRect(&dst_rect
, 0, 480, 640, 0);
1007 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1008 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1009 /* Full, explicit. */
1010 SetRect(&src_rect
, 0, 0, 640, 480);
1011 SetRect(&dst_rect
, 0, 0, 640, 480);
1012 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1013 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1014 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1016 /* Depth blit inside a BeginScene / EndScene pair */
1017 hr
= IDirect3DDevice2_BeginScene(device
);
1018 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1019 /* From the current depth stencil */
1020 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1021 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1022 /* To the current depth stencil */
1023 hr
= IDirectDrawSurface_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1024 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1025 /* Between unbound surfaces */
1026 hr
= IDirectDrawSurface_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1027 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1028 hr
= IDirect3DDevice2_EndScene(device
);
1029 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1031 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1032 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1033 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1034 * a reliable result(z = 0.0) */
1035 memset(&fx
, 0, sizeof(fx
));
1036 fx
.dwSize
= sizeof(fx
);
1037 U5(fx
).dwFillDepth
= 0;
1038 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1039 ok(SUCCEEDED(hr
), "Failed to clear the source z buffer, hr %#x.\n", hr
);
1041 /* This clears the Z buffer with 1.0 */
1042 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
);
1043 ok(SUCCEEDED(hr
), "Failed to clear the color and z buffers, hr %#x.\n", hr
);
1045 SetRect(&dst_rect
, 0, 0, 320, 240);
1046 hr
= IDirectDrawSurface_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1047 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1048 IDirectDrawSurface_Release(ds3
);
1049 IDirectDrawSurface_Release(ds2
);
1050 IDirectDrawSurface_Release(ds1
);
1052 hr
= IDirect3DDevice2_BeginScene(device
);
1053 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1054 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad1
, 4, 0);
1055 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1056 hr
= IDirect3DDevice2_EndScene(device
);
1057 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1059 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1060 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1061 for (i
= 0; i
< 4; ++i
)
1063 for (j
= 0; j
< 4; ++j
)
1065 unsigned int x
= 80 * ((2 * j
) + 1);
1066 unsigned int y
= 60 * ((2 * i
) + 1);
1067 color
= get_surface_color(rt
, x
, y
);
1068 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1069 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1072 IDirectDrawSurface_Release(rt
);
1074 destroy_viewport(device
, viewport
);
1075 destroy_material(background
);
1076 IDirect3DDevice2_Release(device
);
1077 IDirectDraw2_Release(ddraw
);
1078 DestroyWindow(window
);
1081 static void test_texture_load_ckey(void)
1083 IDirectDraw2
*ddraw
= NULL
;
1084 IDirectDrawSurface
*src
= NULL
;
1085 IDirectDrawSurface
*dst
= NULL
;
1086 IDirect3DTexture
*src_tex
= NULL
;
1087 IDirect3DTexture
*dst_tex
= NULL
;
1092 ddraw
= create_ddraw();
1093 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1094 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1095 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1097 memset(&ddsd
, 0, sizeof(ddsd
));
1098 ddsd
.dwSize
= sizeof(ddsd
);
1099 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1100 ddsd
.dwHeight
= 128;
1102 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1103 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1104 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1105 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1106 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1107 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1109 hr
= IDirectDrawSurface_QueryInterface(src
, &IID_IDirect3DTexture
, (void **)&src_tex
);
1110 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get Direct3DTexture interface, hr %#x.\n", hr
);
1113 /* 64 bit ddraw does not support d3d */
1114 skip("Could not get Direct3DTexture interface, skipping texture::Load color keying tests.\n");
1117 hr
= IDirectDrawSurface_QueryInterface(dst
, &IID_IDirect3DTexture
, (void **)&dst_tex
);
1118 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture interface, hr %#x.\n", hr
);
1120 /* No surface has a color key */
1121 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1122 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDCAPS
), "Got unexpected hr %#x.\n", hr
);
1125 /* Testbot Windows NT VMs */
1126 skip("IDirect3DTexture::Load does not work, skipping color keying tests.\n");
1130 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1131 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1132 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1133 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1134 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1136 /* Source surface has a color key */
1137 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1138 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1139 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1140 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1141 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1142 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1143 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1144 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1145 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1147 /* Both surfaces have a color key: Dest ckey is overwritten */
1148 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1149 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1150 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1151 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1152 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1153 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1154 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1155 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1156 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1158 /* Only the destination has a color key: It is not deleted */
1159 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1160 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1161 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1162 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1163 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1164 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1165 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1166 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1167 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1168 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1171 if (dst_tex
) IDirect3DTexture_Release(dst_tex
);
1172 if (src_tex
) IDirect3DTexture_Release(src_tex
);
1173 if (dst
) IDirectDrawSurface_Release(dst
);
1174 if (src
) IDirectDrawSurface_Release(src
);
1175 if (ddraw
) IDirectDraw2_Release(ddraw
);
1178 static ULONG
get_refcount(IUnknown
*test_iface
)
1180 IUnknown_AddRef(test_iface
);
1181 return IUnknown_Release(test_iface
);
1184 static void test_viewport(void)
1186 IDirectDraw2
*ddraw
;
1189 ULONG ref
, old_d3d_ref
;
1190 IDirect3DViewport
*viewport
;
1191 IDirect3DViewport2
*viewport2
, *another_vp
, *test_vp
;
1192 IDirect3DViewport3
*viewport3
;
1193 IDirectDrawGammaControl
*gamma
;
1195 IDirect3DDevice2
*device
;
1198 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1199 0, 0, 640, 480, 0, 0, 0, 0);
1200 ddraw
= create_ddraw();
1201 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1202 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1204 skip("Failed to create a 3D device, skipping test.\n");
1205 IDirectDraw_Release(ddraw
);
1206 DestroyWindow(window
);
1210 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
1211 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get d3d interface, hr %#x.\n", hr
);
1214 skip("D3D interface is not available, skipping test.\n");
1215 IDirectDraw2_Release(ddraw
);
1218 old_d3d_ref
= get_refcount((IUnknown
*)d3d
);
1220 hr
= IDirect3D2_CreateViewport(d3d
, &viewport2
, NULL
);
1221 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1222 ref
= get_refcount((IUnknown
*)viewport2
);
1223 ok(ref
== 1, "Initial IDirect3DViewport2 refcount is %u\n", ref
);
1224 ref
= get_refcount((IUnknown
*)d3d
);
1225 ok(ref
== old_d3d_ref
, "IDirect3D2 refcount is %u\n", ref
);
1227 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1228 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1229 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
1230 ok(gamma
== NULL
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1231 if (SUCCEEDED(hr
)) IDirectDrawGammaControl_Release(gamma
);
1232 /* NULL iid: Segfaults */
1234 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport
, (void **)&viewport
);
1235 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport, hr %#x.\n", hr
);
1238 ref
= get_refcount((IUnknown
*)viewport
);
1239 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
1240 ref
= get_refcount((IUnknown
*)viewport2
);
1241 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
1242 IDirect3DViewport_Release(viewport
);
1246 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport3
, (void **)&viewport3
);
1247 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to QI IDirect3DViewport3, hr %#x.\n", hr
);
1250 ref
= get_refcount((IUnknown
*)viewport2
);
1251 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
1252 ref
= get_refcount((IUnknown
*)viewport3
);
1253 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1254 IDirect3DViewport3_Release(viewport3
);
1257 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IUnknown
, (void **)&unknown
);
1258 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#x.\n", hr
);
1261 ref
= get_refcount((IUnknown
*)viewport2
);
1262 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
1263 ref
= get_refcount(unknown
);
1264 ok(ref
== 2, "IUnknown refcount is %u\n", ref
);
1265 IUnknown_Release(unknown
);
1268 /* AddViewport(NULL): Segfault */
1269 hr
= IDirect3DDevice2_DeleteViewport(device
, NULL
);
1270 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1271 hr
= IDirect3DDevice2_GetCurrentViewport(device
, NULL
);
1272 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1274 hr
= IDirect3D2_CreateViewport(d3d
, &another_vp
, NULL
);
1275 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1277 /* Setting a viewport not in the viewport list fails */
1278 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1279 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1281 hr
= IDirect3DDevice2_AddViewport(device
, viewport2
);
1282 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1283 ref
= get_refcount((IUnknown
*) viewport2
);
1284 ok(ref
== 2, "viewport2 refcount is %d\n", ref
);
1285 hr
= IDirect3DDevice2_AddViewport(device
, another_vp
);
1286 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1287 ref
= get_refcount((IUnknown
*) another_vp
);
1288 ok(ref
== 2, "another_vp refcount is %d\n", ref
);
1290 test_vp
= (IDirect3DViewport2
*) 0xbaadc0de;
1291 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1292 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1293 ok(test_vp
== (IDirect3DViewport2
*) 0xbaadc0de, "Got unexpected pointer %p\n", test_vp
);
1295 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1296 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1297 ref
= get_refcount((IUnknown
*) viewport2
);
1298 ok(ref
== 3, "viewport2 refcount is %d\n", ref
);
1299 ref
= get_refcount((IUnknown
*) device
);
1300 ok(ref
== 1, "device refcount is %d\n", ref
);
1303 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1304 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1305 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1306 ref
= get_refcount((IUnknown
*) viewport2
);
1307 ok(ref
== 4, "viewport2 refcount is %d\n", ref
);
1308 if(test_vp
) IDirect3DViewport2_Release(test_vp
);
1310 /* GetCurrentViewport with a viewport set and NULL input param: Segfault */
1312 /* Cannot set the viewport to NULL */
1313 hr
= IDirect3DDevice2_SetCurrentViewport(device
, NULL
);
1314 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to set viewport to NULL, hr %#x.\n", hr
);
1316 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1317 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1318 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1319 if(test_vp
) IDirect3DViewport2_Release(test_vp
);
1321 /* SetCurrentViewport properly releases the old viewport's reference */
1322 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1323 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1324 ref
= get_refcount((IUnknown
*) viewport2
);
1325 ok(ref
== 2, "viewport2 refcount is %d\n", ref
);
1326 ref
= get_refcount((IUnknown
*) another_vp
);
1327 ok(ref
== 3, "another_vp refcount is %d\n", ref
);
1329 /* Deleting the viewport removes the reference added by AddViewport, but not
1330 * the one added by SetCurrentViewport. */
1331 hr
= IDirect3DDevice2_DeleteViewport(device
, another_vp
);
1332 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#x.\n", hr
);
1333 ref
= get_refcount((IUnknown
*) another_vp
);
1334 todo_wine
ok(ref
== 2, "IDirect3DViewport2 refcount is %d\n", ref
);
1336 /* GetCurrentViewport fails though */
1338 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1339 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1340 ok(test_vp
== NULL
, "Got unexpected viewport %p\n", test_vp
);
1341 if(test_vp
) IDirect3DViewport2_Release(test_vp
);
1343 /* Setting a different viewport does not free the leaked reference. How
1344 * do I get rid of it? Leak the viewport for now. */
1345 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1346 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1347 ref
= get_refcount((IUnknown
*) viewport2
);
1348 ok(ref
== 3, "viewport2 refcount is %d\n", ref
);
1349 ref
= get_refcount((IUnknown
*) another_vp
);
1350 todo_wine
ok(ref
== 2, "another_vp refcount is %d\n", ref
);
1352 /* Destroying the device removes the viewport, but does not free the reference
1353 * added by SetCurrentViewport. */
1354 IDirect3DDevice2_Release(device
);
1355 ref
= get_refcount((IUnknown
*) viewport2
);
1356 todo_wine
ok(ref
== 2, "viewport2 refcount is %d\n", ref
);
1358 IDirect3DViewport2_Release(another_vp
);
1359 IDirect3DViewport2_Release(viewport2
);
1360 IDirect3D2_Release(d3d
);
1361 DestroyWindow(window
);
1362 IDirectDraw2_Release(ddraw
);
1365 static void test_zenable(void)
1367 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1368 static D3DTLVERTEX tquad
[] =
1370 {{ 0.0f
}, {480.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1371 {{ 0.0f
}, { 0.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1372 {{640.0f
}, {480.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1373 {{640.0f
}, { 0.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1375 IDirect3DMaterial2
*background
;
1376 IDirect3DViewport2
*viewport
;
1377 IDirect3DDevice2
*device
;
1378 IDirectDrawSurface
*rt
;
1379 IDirectDraw2
*ddraw
;
1386 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1387 0, 0, 640, 480, 0, 0, 0, 0);
1388 ddraw
= create_ddraw();
1389 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1390 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1392 skip("Failed to create a 3D device, skipping test.\n");
1393 IDirectDraw2_Release(ddraw
);
1394 DestroyWindow(window
);
1398 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1399 viewport
= create_viewport(device
, 0, 0, 640, 480);
1400 viewport_set_background(device
, viewport
, background
);
1401 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1402 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1404 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1405 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
1407 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1408 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1409 hr
= IDirect3DDevice2_BeginScene(device
);
1410 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1411 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, tquad
, 4, 0);
1412 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1413 hr
= IDirect3DDevice2_EndScene(device
);
1414 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1416 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1417 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1418 for (i
= 0; i
< 4; ++i
)
1420 for (j
= 0; j
< 4; ++j
)
1422 x
= 80 * ((2 * j
) + 1);
1423 y
= 60 * ((2 * i
) + 1);
1424 color
= get_surface_color(rt
, x
, y
);
1425 ok(compare_color(color
, 0x0000ff00, 1),
1426 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1429 IDirectDrawSurface_Release(rt
);
1431 destroy_viewport(device
, viewport
);
1432 destroy_material(background
);
1433 IDirect3DDevice2_Release(device
);
1434 IDirectDraw2_Release(ddraw
);
1435 DestroyWindow(window
);
1438 static void test_ck_rgba(void)
1440 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1441 static D3DTLVERTEX tquad
[] =
1443 {{ 0.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1444 {{ 0.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1445 {{640.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1446 {{640.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1447 {{ 0.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1448 {{ 0.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1449 {{640.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1450 {{640.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1454 D3DCOLOR fill_color
;
1462 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x000000ff},
1463 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x000000ff},
1464 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00},
1465 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1466 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00807f00},
1467 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x0000ff00},
1468 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00},
1469 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1472 D3DTEXTUREHANDLE texture_handle
;
1473 IDirect3DMaterial2
*background
;
1474 IDirectDrawSurface
*surface
;
1475 IDirect3DViewport2
*viewport
;
1476 IDirect3DTexture2
*texture
;
1477 DDSURFACEDESC surface_desc
;
1478 IDirect3DDevice2
*device
;
1479 IDirectDrawSurface
*rt
;
1480 IDirectDraw2
*ddraw
;
1487 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1488 0, 0, 640, 480, 0, 0, 0, 0);
1489 ddraw
= create_ddraw();
1490 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1491 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1493 skip("Failed to create a 3D device, skipping test.\n");
1494 IDirectDraw2_Release(ddraw
);
1495 DestroyWindow(window
);
1499 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1500 viewport
= create_viewport(device
, 0, 0, 640, 480);
1501 viewport_set_background(device
, viewport
, background
);
1502 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1503 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1505 memset(&surface_desc
, 0, sizeof(surface_desc
));
1506 surface_desc
.dwSize
= sizeof(surface_desc
);
1507 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1508 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1509 surface_desc
.dwWidth
= 256;
1510 surface_desc
.dwHeight
= 256;
1511 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1512 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1513 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1514 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1515 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1516 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1517 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1518 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1519 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1520 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1521 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1522 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1523 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1524 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
1525 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1526 IDirect3DTexture2_Release(texture
);
1528 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1529 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1530 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1531 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1532 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1533 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1535 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1536 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1538 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
1540 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1541 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1542 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1543 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1545 memset(&fx
, 0, sizeof(fx
));
1546 fx
.dwSize
= sizeof(fx
);
1547 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1548 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1549 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1551 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
1552 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1553 hr
= IDirect3DDevice2_BeginScene(device
);
1554 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1555 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
1556 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1557 hr
= IDirect3DDevice2_EndScene(device
);
1558 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1560 color
= get_surface_color(rt
, 320, 240);
1562 todo_wine
ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1563 tests
[i
].result1
, i
, color
);
1565 ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1566 tests
[i
].result1
, i
, color
);
1568 U5(fx
).dwFillColor
= 0xff0000ff;
1569 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1570 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1572 hr
= IDirect3DDevice2_BeginScene(device
);
1573 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1574 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[4], 4, 0);
1575 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1576 hr
= IDirect3DDevice2_EndScene(device
);
1577 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1579 /* This tests that fragments that are masked out by the color key are
1580 * discarded, instead of just fully transparent. */
1581 color
= get_surface_color(rt
, 320, 240);
1583 todo_wine
ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1584 tests
[i
].result2
, i
, color
);
1586 ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1587 tests
[i
].result2
, i
, color
);
1590 IDirectDrawSurface_Release(rt
);
1591 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1592 ok(SUCCEEDED(hr
), "Failed to unset texture, hr %#x.\n", hr
);
1593 IDirectDrawSurface_Release(surface
);
1594 destroy_viewport(device
, viewport
);
1595 destroy_material(background
);
1596 IDirect3DDevice2_Release(device
);
1597 IDirectDraw2_Release(ddraw
);
1598 DestroyWindow(window
);
1601 static void test_ck_default(void)
1603 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1604 static D3DTLVERTEX tquad
[] =
1606 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1607 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1608 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1609 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1611 IDirectDrawSurface
*surface
, *rt
;
1612 D3DTEXTUREHANDLE texture_handle
;
1613 IDirect3DMaterial2
*background
;
1614 IDirect3DViewport2
*viewport
;
1615 DDSURFACEDESC surface_desc
;
1616 IDirect3DTexture2
*texture
;
1617 IDirect3DDevice2
*device
;
1618 IDirectDraw2
*ddraw
;
1625 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1626 0, 0, 640, 480, 0, 0, 0, 0);
1627 ddraw
= create_ddraw();
1628 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1629 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1631 skip("Failed to create a 3D device, skipping test.\n");
1632 IDirectDraw2_Release(ddraw
);
1633 DestroyWindow(window
);
1637 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1638 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1640 background
= create_diffuse_material(device
, 0.0, 1.0f
, 0.0f
, 1.0f
);
1641 viewport
= create_viewport(device
, 0, 0, 640, 480);
1642 viewport_set_background(device
, viewport
, background
);
1643 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1644 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1646 memset(&surface_desc
, 0, sizeof(surface_desc
));
1647 surface_desc
.dwSize
= sizeof(surface_desc
);
1648 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1649 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1650 surface_desc
.dwWidth
= 256;
1651 surface_desc
.dwHeight
= 256;
1652 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1653 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1654 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1655 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1656 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1657 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1658 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
1659 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
1660 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1661 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1662 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1663 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1664 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
1665 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1666 IDirect3DTexture_Release(texture
);
1668 memset(&fx
, 0, sizeof(fx
));
1669 fx
.dwSize
= sizeof(fx
);
1670 U5(fx
).dwFillColor
= 0x000000ff;
1671 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1672 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
1674 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1675 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1676 hr
= IDirect3DDevice2_BeginScene(device
);
1677 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1678 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1679 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
1680 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1681 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1682 ok(!value
, "Got unexpected color keying state %#x.\n", value
);
1683 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
1684 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1685 hr
= IDirect3DDevice2_EndScene(device
);
1686 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1687 color
= get_surface_color(rt
, 320, 240);
1688 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1690 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1691 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1692 hr
= IDirect3DDevice2_BeginScene(device
);
1693 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1694 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
1695 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1696 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
1697 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1698 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1699 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1700 ok(!!value
, "Got unexpected color keying state %#x.\n", value
);
1701 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1702 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
1703 hr
= IDirect3DDevice2_EndScene(device
);
1704 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1705 color
= get_surface_color(rt
, 320, 240);
1706 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1708 IDirectDrawSurface_Release(surface
);
1709 destroy_viewport(device
, viewport
);
1710 destroy_material(background
);
1711 IDirectDrawSurface_Release(rt
);
1712 IDirect3DDevice2_Release(device
);
1713 IDirectDraw2_Release(ddraw
);
1714 DestroyWindow(window
);
1717 static void test_ck_complex(void)
1719 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
1720 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
1721 DDSURFACEDESC surface_desc
;
1722 IDirect3DDevice2
*device
;
1723 DDCOLORKEY color_key
;
1724 IDirectDraw2
*ddraw
;
1730 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1731 0, 0, 640, 480, 0, 0, 0, 0);
1732 ddraw
= create_ddraw();
1733 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1734 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
1736 skip("Failed to create a 3D device, skipping test.\n");
1737 DestroyWindow(window
);
1738 IDirectDraw2_Release(ddraw
);
1741 IDirect3DDevice2_Release(device
);
1743 memset(&surface_desc
, 0, sizeof(surface_desc
));
1744 surface_desc
.dwSize
= sizeof(surface_desc
);
1745 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1746 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
1747 surface_desc
.dwWidth
= 128;
1748 surface_desc
.dwHeight
= 128;
1749 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1750 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1752 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1753 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1754 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1755 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1756 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1757 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1758 memset(&color_key
, 0, sizeof(color_key
));
1759 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1760 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1761 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1762 color_key
.dwColorSpaceLowValue
);
1763 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1764 color_key
.dwColorSpaceHighValue
);
1767 IDirectDrawSurface_AddRef(mipmap
);
1768 for (i
= 0; i
< 7; ++i
)
1770 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
1771 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
1773 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1774 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
1775 color_key
.dwColorSpaceLowValue
= 0x000000ff;
1776 color_key
.dwColorSpaceHighValue
= 0x000000ff;
1777 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1778 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x, i %u.\n", hr
, i
);
1779 memset(&color_key
, 0, sizeof(color_key
));
1780 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1781 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x, i %u.\n", hr
, i
);
1782 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
1783 color_key
.dwColorSpaceLowValue
, i
);
1784 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
1785 color_key
.dwColorSpaceHighValue
, i
);
1787 IDirectDrawSurface_Release(mipmap
);
1791 memset(&color_key
, 0, sizeof(color_key
));
1792 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1793 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1794 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1795 color_key
.dwColorSpaceLowValue
);
1796 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1797 color_key
.dwColorSpaceHighValue
);
1799 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
1800 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
1801 IDirectDrawSurface_Release(mipmap
);
1802 refcount
= IDirectDrawSurface_Release(surface
);
1803 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1805 memset(&surface_desc
, 0, sizeof(surface_desc
));
1806 surface_desc
.dwSize
= sizeof(surface_desc
);
1807 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
1808 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
1809 surface_desc
.dwBackBufferCount
= 1;
1810 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1811 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1813 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1814 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1815 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1816 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1817 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1818 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1819 memset(&color_key
, 0, sizeof(color_key
));
1820 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1821 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1822 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1823 color_key
.dwColorSpaceLowValue
);
1824 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1825 color_key
.dwColorSpaceHighValue
);
1827 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
1828 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
1830 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1831 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
1832 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1833 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1834 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1835 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1836 memset(&color_key
, 0, sizeof(color_key
));
1837 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1838 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1839 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1840 color_key
.dwColorSpaceLowValue
);
1841 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1842 color_key
.dwColorSpaceHighValue
);
1844 IDirectDrawSurface_Release(tmp
);
1846 refcount
= IDirectDrawSurface_Release(surface
);
1847 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1848 refcount
= IDirectDraw2_Release(ddraw
);
1849 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1850 DestroyWindow(window
);
1856 REFIID refcount_iid
;
1860 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
1861 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
1863 ULONG refcount
, expected_refcount
;
1864 IUnknown
*iface1
, *iface2
;
1868 for (i
= 0; i
< entry_count
; ++i
)
1870 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
1871 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
1874 for (j
= 0; j
< entry_count
; ++j
)
1876 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
1877 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
1880 expected_refcount
= 0;
1881 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
1882 ++expected_refcount
;
1883 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
1884 ++expected_refcount
;
1885 refcount
= IUnknown_Release(iface2
);
1886 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
1887 refcount
, test_name
, i
, j
, expected_refcount
);
1891 expected_refcount
= 0;
1892 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
1893 ++expected_refcount
;
1894 refcount
= IUnknown_Release(iface1
);
1895 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
1896 refcount
, test_name
, i
, expected_refcount
);
1901 static void test_surface_qi(void)
1903 static const struct qi_test tests
[] =
1905 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
1906 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
1907 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
1908 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1909 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
1910 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
1911 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
1912 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
1913 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
1914 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
1915 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
1916 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
1917 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
1918 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
1919 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
1920 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
1921 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
1922 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
1923 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
1924 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
1925 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
1926 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
1927 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
1928 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
1929 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
1930 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
1931 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
1932 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
1933 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
1934 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
1935 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
1936 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
1937 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
1938 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
1939 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
1942 IDirectDrawSurface
*surface
;
1943 DDSURFACEDESC surface_desc
;
1944 IDirect3DDevice2
*device
;
1945 IDirectDraw2
*ddraw
;
1949 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
1951 win_skip("DirectDrawCreateEx not available, skipping test.\n");
1955 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1956 0, 0, 640, 480, 0, 0, 0, 0);
1957 ddraw
= create_ddraw();
1958 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1959 /* Try to create a D3D device to see if the ddraw implementation supports
1960 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
1961 * doesn't support e.g. the IDirect3DTexture interfaces. */
1962 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1964 skip("Failed to create a 3D device, skipping test.\n");
1965 IDirectDraw2_Release(ddraw
);
1966 DestroyWindow(window
);
1969 IDirect3DDevice_Release(device
);
1971 memset(&surface_desc
, 0, sizeof(surface_desc
));
1972 surface_desc
.dwSize
= sizeof(surface_desc
);
1973 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1974 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1975 surface_desc
.dwWidth
= 512;
1976 surface_desc
.dwHeight
= 512;
1977 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1978 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1980 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface
, tests
, sizeof(tests
) / sizeof(*tests
));
1982 IDirectDrawSurface_Release(surface
);
1983 IDirectDraw2_Release(ddraw
);
1984 DestroyWindow(window
);
1987 static void test_device_qi(void)
1989 static const struct qi_test tests
[] =
1991 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
1992 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
1993 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
1994 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1995 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
1996 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
1997 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
1998 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
1999 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
2000 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
2001 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
2002 {&IID_IDirect3DDevice2
, &IID_IDirect3DDevice2
, S_OK
},
2003 {&IID_IDirect3DDevice
, &IID_IDirect3DDevice2
, S_OK
},
2004 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
2005 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
2006 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
2007 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
2008 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
2009 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
2010 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
2011 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
2012 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
2013 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
2014 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
2015 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
2016 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
2017 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
2018 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
2019 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
2020 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
2021 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
2022 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
2023 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
2024 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
2025 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
2026 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
2027 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
2028 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
2029 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
2030 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
2031 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
2032 {&IID_IUnknown
, &IID_IDirect3DDevice2
, S_OK
},
2035 IDirect3DDevice2
*device
;
2036 IDirectDraw2
*ddraw
;
2039 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2040 0, 0, 640, 480, 0, 0, 0, 0);
2041 ddraw
= create_ddraw();
2042 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2043 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2045 skip("Failed to create a 3D device, skipping test.\n");
2046 IDirectDraw2_Release(ddraw
);
2047 DestroyWindow(window
);
2051 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice2
, tests
, sizeof(tests
) / sizeof(*tests
));
2053 IDirect3DDevice2_Release(device
);
2054 IDirectDraw2_Release(ddraw
);
2055 DestroyWindow(window
);
2058 static void test_wndproc(void)
2060 LONG_PTR proc
, ddraw_proc
;
2061 IDirectDraw2
*ddraw
;
2067 static const UINT messages
[] =
2069 WM_WINDOWPOSCHANGING
,
2072 WM_WINDOWPOSCHANGING
,
2078 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2079 ddraw
= create_ddraw();
2080 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2082 wc
.lpfnWndProc
= test_proc
;
2083 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2084 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2086 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2087 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2089 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2090 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2091 (LONG_PTR
)test_proc
, proc
);
2092 expect_messages
= messages
;
2093 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2094 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2095 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2096 expect_messages
= NULL
;
2097 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2098 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2099 (LONG_PTR
)test_proc
, proc
);
2100 ref
= IDirectDraw2_Release(ddraw
);
2101 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2102 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2103 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2104 (LONG_PTR
)test_proc
, proc
);
2106 /* DDSCL_NORMAL doesn't. */
2107 ddraw
= create_ddraw();
2108 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2109 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2110 (LONG_PTR
)test_proc
, proc
);
2111 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2112 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2113 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2114 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2115 (LONG_PTR
)test_proc
, proc
);
2116 ref
= IDirectDraw2_Release(ddraw
);
2117 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2118 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2119 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2120 (LONG_PTR
)test_proc
, proc
);
2122 /* The original window proc is only restored by ddraw if the current
2123 * window proc matches the one ddraw set. This also affects switching
2124 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2125 ddraw
= create_ddraw();
2126 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2127 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2128 (LONG_PTR
)test_proc
, proc
);
2129 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2130 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2131 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2132 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2133 (LONG_PTR
)test_proc
, proc
);
2135 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2136 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2137 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2138 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2139 (LONG_PTR
)test_proc
, proc
);
2140 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2141 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2142 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2143 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2144 (LONG_PTR
)test_proc
, proc
);
2145 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2146 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2147 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2148 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2149 (LONG_PTR
)DefWindowProcA
, proc
);
2150 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2151 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2152 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)ddraw_proc
);
2153 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2154 (LONG_PTR
)DefWindowProcA
, proc
);
2155 ref
= IDirectDraw2_Release(ddraw
);
2156 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2157 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2158 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2159 (LONG_PTR
)test_proc
, proc
);
2161 ddraw
= create_ddraw();
2162 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2163 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2164 (LONG_PTR
)test_proc
, proc
);
2165 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2166 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2167 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2168 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2169 (LONG_PTR
)test_proc
, proc
);
2170 ref
= IDirectDraw2_Release(ddraw
);
2171 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2172 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2173 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2174 (LONG_PTR
)DefWindowProcA
, proc
);
2176 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2177 expect_messages
= NULL
;
2178 DestroyWindow(window
);
2179 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2182 static void test_window_style(void)
2184 LONG style
, exstyle
, tmp
;
2185 RECT fullscreen_rect
, r
;
2186 IDirectDraw2
*ddraw
;
2191 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2192 0, 0, 100, 100, 0, 0, 0, 0);
2193 ddraw
= create_ddraw();
2194 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2196 style
= GetWindowLongA(window
, GWL_STYLE
);
2197 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2198 SetRect(&fullscreen_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
2200 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2201 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2203 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2204 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2205 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2206 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2208 GetWindowRect(window
, &r
);
2209 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2210 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2211 r
.left
, r
.top
, r
.right
, r
.bottom
);
2212 GetClientRect(window
, &r
);
2213 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2215 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2216 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2218 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2219 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2220 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2221 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2223 ref
= IDirectDraw2_Release(ddraw
);
2224 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2226 DestroyWindow(window
);
2229 static void test_redundant_mode_set(void)
2231 DDSURFACEDESC surface_desc
= {0};
2232 IDirectDraw2
*ddraw
;
2238 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2239 0, 0, 100, 100, 0, 0, 0, 0);
2240 ddraw
= create_ddraw();
2241 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2243 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2244 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2246 surface_desc
.dwSize
= sizeof(surface_desc
);
2247 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
2248 ok(SUCCEEDED(hr
), "GetDipslayMode failed, hr %#x.\n", hr
);
2250 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2251 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2252 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2254 GetWindowRect(window
, &r
);
2257 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2258 GetWindowRect(window
, &s
);
2259 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2260 r
.left
, r
.top
, r
.right
, r
.bottom
,
2261 s
.left
, s
.top
, s
.right
, s
.bottom
);
2263 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2264 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2265 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2267 GetWindowRect(window
, &s
);
2268 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2269 r
.left
, r
.top
, r
.right
, r
.bottom
,
2270 s
.left
, s
.top
, s
.right
, s
.bottom
);
2272 ref
= IDirectDraw2_Release(ddraw
);
2273 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2275 DestroyWindow(window
);
2278 static SIZE screen_size
, screen_size2
;
2280 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2282 if (message
== WM_SIZE
)
2284 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2285 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2288 return test_proc(hwnd
, message
, wparam
, lparam
);
2291 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2293 if (message
== WM_SIZE
)
2295 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2296 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2299 return test_proc(hwnd
, message
, wparam
, lparam
);
2302 static void test_coop_level_mode_set(void)
2304 IDirectDrawSurface
*primary
;
2305 RECT fullscreen_rect
, r
, s
;
2306 IDirectDraw2
*ddraw
;
2309 HWND window
, window2
;
2314 static const UINT exclusive_messages
[] =
2316 WM_WINDOWPOSCHANGING
,
2317 WM_WINDOWPOSCHANGED
,
2323 static const UINT normal_messages
[] =
2329 ddraw
= create_ddraw();
2330 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2332 wc
.lpfnWndProc
= mode_set_proc
;
2333 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2334 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2335 wc
.lpfnWndProc
= mode_set_proc2
;
2336 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
2337 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2339 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2340 0, 0, 100, 100, 0, 0, 0, 0);
2341 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2342 0, 0, 100, 100, 0, 0, 0, 0);
2344 SetRect(&fullscreen_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
2345 SetRect(&s
, 0, 0, 640, 480);
2347 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2348 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2350 GetWindowRect(window
, &r
);
2351 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2352 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2353 r
.left
, r
.top
, r
.right
, r
.bottom
);
2355 memset(&ddsd
, 0, sizeof(ddsd
));
2356 ddsd
.dwSize
= sizeof(ddsd
);
2357 ddsd
.dwFlags
= DDSD_CAPS
;
2358 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2360 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2361 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2362 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2363 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2364 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2365 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2366 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2367 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2369 GetWindowRect(window
, &r
);
2370 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2371 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2372 r
.left
, r
.top
, r
.right
, r
.bottom
);
2374 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2375 expect_messages
= exclusive_messages
;
2379 hr
= set_display_mode(ddraw
, 640, 480);
2380 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2382 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2383 expect_messages
= NULL
;
2384 ok(screen_size
.cx
== s
.right
&& screen_size
.cy
== s
.bottom
,
2385 "Expected screen size %ux%u, got %ux%u.\n",
2386 s
.right
, s
.bottom
, screen_size
.cx
, screen_size
.cy
);
2388 GetWindowRect(window
, &r
);
2389 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2390 s
.left
, s
.top
, s
.right
, s
.bottom
,
2391 r
.left
, r
.top
, r
.right
, r
.bottom
);
2393 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2394 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2395 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2396 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2397 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2398 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2399 IDirectDrawSurface_Release(primary
);
2401 memset(&ddsd
, 0, sizeof(ddsd
));
2402 ddsd
.dwSize
= sizeof(ddsd
);
2403 ddsd
.dwFlags
= DDSD_CAPS
;
2404 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2406 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2407 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2408 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2409 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2410 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2411 s
.right
- s
.left
, ddsd
.dwWidth
);
2412 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2413 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2415 GetWindowRect(window
, &r
);
2416 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2417 s
.left
, s
.top
, s
.right
, s
.bottom
,
2418 r
.left
, r
.top
, r
.right
, r
.bottom
);
2420 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2421 expect_messages
= exclusive_messages
;
2425 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2426 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2428 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2429 expect_messages
= NULL
;
2430 ok(screen_size
.cx
== fullscreen_rect
.right
&& screen_size
.cy
== fullscreen_rect
.bottom
,
2431 "Expected screen size %ux%u, got %ux%u.\n",
2432 fullscreen_rect
.right
, fullscreen_rect
.bottom
, screen_size
.cx
, screen_size
.cy
);
2434 GetWindowRect(window
, &r
);
2435 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2436 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2437 r
.left
, r
.top
, r
.right
, r
.bottom
);
2439 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2440 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2441 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2442 s
.right
- s
.left
, ddsd
.dwWidth
);
2443 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2444 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2445 IDirectDrawSurface_Release(primary
);
2447 memset(&ddsd
, 0, sizeof(ddsd
));
2448 ddsd
.dwSize
= sizeof(ddsd
);
2449 ddsd
.dwFlags
= DDSD_CAPS
;
2450 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2452 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2453 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2454 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2455 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2456 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2457 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2458 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2459 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2461 GetWindowRect(window
, &r
);
2462 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2463 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2464 r
.left
, r
.top
, r
.right
, r
.bottom
);
2466 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2467 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2469 GetWindowRect(window
, &r
);
2470 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2471 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2472 r
.left
, r
.top
, r
.right
, r
.bottom
);
2474 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2475 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2476 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2477 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2478 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2479 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2480 IDirectDrawSurface_Release(primary
);
2482 memset(&ddsd
, 0, sizeof(ddsd
));
2483 ddsd
.dwSize
= sizeof(ddsd
);
2484 ddsd
.dwFlags
= DDSD_CAPS
;
2485 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2487 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2488 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2489 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2490 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2491 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2492 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2493 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2494 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2496 GetWindowRect(window
, &r
);
2497 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2498 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2499 r
.left
, r
.top
, r
.right
, r
.bottom
);
2501 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2502 expect_messages
= normal_messages
;
2506 hr
= set_display_mode(ddraw
, 640, 480);
2507 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
2509 win_skip("Broken SetDisplayMode(), skipping remaining tests.\n");
2510 IDirectDrawSurface_Release(primary
);
2511 IDirectDraw2_Release(ddraw
);
2514 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2516 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2517 expect_messages
= NULL
;
2518 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2520 GetWindowRect(window
, &r
);
2521 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2522 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2523 r
.left
, r
.top
, r
.right
, r
.bottom
);
2525 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2526 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2527 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2528 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2529 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2530 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2531 IDirectDrawSurface_Release(primary
);
2533 memset(&ddsd
, 0, sizeof(ddsd
));
2534 ddsd
.dwSize
= sizeof(ddsd
);
2535 ddsd
.dwFlags
= DDSD_CAPS
;
2536 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2538 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2539 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2540 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2541 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2542 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2543 s
.right
- s
.left
, ddsd
.dwWidth
);
2544 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2545 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2547 GetWindowRect(window
, &r
);
2548 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2549 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2550 r
.left
, r
.top
, r
.right
, r
.bottom
);
2552 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2553 expect_messages
= normal_messages
;
2557 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2558 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2560 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2561 expect_messages
= NULL
;
2562 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2564 GetWindowRect(window
, &r
);
2565 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2566 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2567 r
.left
, r
.top
, r
.right
, r
.bottom
);
2569 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2570 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2571 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2572 s
.right
- s
.left
, ddsd
.dwWidth
);
2573 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2574 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2575 IDirectDrawSurface_Release(primary
);
2577 memset(&ddsd
, 0, sizeof(ddsd
));
2578 ddsd
.dwSize
= sizeof(ddsd
);
2579 ddsd
.dwFlags
= DDSD_CAPS
;
2580 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2582 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2583 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2584 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2585 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2586 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2587 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2588 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2589 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2591 GetWindowRect(window
, &r
);
2592 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2593 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2594 r
.left
, r
.top
, r
.right
, r
.bottom
);
2596 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
2597 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
2598 * not DDSCL_FULLSCREEN. */
2599 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2600 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2602 GetWindowRect(window
, &r
);
2603 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2604 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2605 r
.left
, r
.top
, r
.right
, r
.bottom
);
2607 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2608 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2609 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2610 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2611 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2612 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2613 IDirectDrawSurface_Release(primary
);
2615 memset(&ddsd
, 0, sizeof(ddsd
));
2616 ddsd
.dwSize
= sizeof(ddsd
);
2617 ddsd
.dwFlags
= DDSD_CAPS
;
2618 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2620 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2621 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2622 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2623 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2624 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2625 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2626 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2627 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2629 GetWindowRect(window
, &r
);
2630 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2631 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2632 r
.left
, r
.top
, r
.right
, r
.bottom
);
2634 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2635 expect_messages
= normal_messages
;
2639 hr
= set_display_mode(ddraw
, 640, 480);
2640 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2642 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2643 expect_messages
= NULL
;
2644 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2646 GetWindowRect(window
, &r
);
2647 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2648 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2649 r
.left
, r
.top
, r
.right
, r
.bottom
);
2651 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2652 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2653 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2654 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2655 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2656 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2657 IDirectDrawSurface_Release(primary
);
2659 memset(&ddsd
, 0, sizeof(ddsd
));
2660 ddsd
.dwSize
= sizeof(ddsd
);
2661 ddsd
.dwFlags
= DDSD_CAPS
;
2662 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2664 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2665 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2666 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2667 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2668 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2669 s
.right
- s
.left
, ddsd
.dwWidth
);
2670 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2671 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2673 GetWindowRect(window
, &r
);
2674 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2675 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2676 r
.left
, r
.top
, r
.right
, r
.bottom
);
2678 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2679 expect_messages
= normal_messages
;
2683 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2684 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2686 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2687 expect_messages
= NULL
;
2688 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2690 GetWindowRect(window
, &r
);
2691 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2692 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2693 r
.left
, r
.top
, r
.right
, r
.bottom
);
2695 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2696 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2697 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2698 s
.right
- s
.left
, ddsd
.dwWidth
);
2699 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2700 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2701 IDirectDrawSurface_Release(primary
);
2703 memset(&ddsd
, 0, sizeof(ddsd
));
2704 ddsd
.dwSize
= sizeof(ddsd
);
2705 ddsd
.dwFlags
= DDSD_CAPS
;
2706 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2708 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2709 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2710 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2711 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2712 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2713 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2714 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2715 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2716 IDirectDrawSurface_Release(primary
);
2718 GetWindowRect(window
, &r
);
2719 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2720 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2721 r
.left
, r
.top
, r
.right
, r
.bottom
);
2723 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
2724 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2725 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2726 hr
= set_display_mode(ddraw
, 640, 480);
2727 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2729 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2730 expect_messages
= exclusive_messages
;
2734 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2735 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2737 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2738 expect_messages
= NULL
;
2739 ok(screen_size
.cx
== fullscreen_rect
.right
&& screen_size
.cy
== fullscreen_rect
.bottom
,
2740 "Expected screen size %ux%u, got %ux%u.\n",
2741 fullscreen_rect
.right
, fullscreen_rect
.bottom
, screen_size
.cx
, screen_size
.cy
);
2743 GetWindowRect(window
, &r
);
2744 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2745 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2746 r
.left
, r
.top
, r
.right
, r
.bottom
);
2748 memset(&ddsd
, 0, sizeof(ddsd
));
2749 ddsd
.dwSize
= sizeof(ddsd
);
2750 ddsd
.dwFlags
= DDSD_CAPS
;
2751 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2753 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2754 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2755 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2756 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2757 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2758 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2759 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2760 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2761 IDirectDrawSurface_Release(primary
);
2763 /* The screen restore is a property of DDSCL_EXCLUSIVE */
2764 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2765 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2766 hr
= set_display_mode(ddraw
, 640, 480);
2767 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2769 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2770 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2772 memset(&ddsd
, 0, sizeof(ddsd
));
2773 ddsd
.dwSize
= sizeof(ddsd
);
2774 ddsd
.dwFlags
= DDSD_CAPS
;
2775 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2777 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2778 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2779 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2780 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2781 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2782 s
.right
- s
.left
, ddsd
.dwWidth
);
2783 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2784 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2785 IDirectDrawSurface_Release(primary
);
2787 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2788 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2790 /* If the window is changed at the same time, messages are sent to the new window. */
2791 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2792 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2793 hr
= set_display_mode(ddraw
, 640, 480);
2794 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2796 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2797 expect_messages
= exclusive_messages
;
2800 screen_size2
.cx
= 0;
2801 screen_size2
.cy
= 0;
2803 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
2804 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2806 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2807 expect_messages
= NULL
;
2808 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n",
2809 screen_size
.cx
, screen_size
.cy
);
2810 ok(screen_size2
.cx
== fullscreen_rect
.right
&& screen_size2
.cy
== fullscreen_rect
.bottom
,
2811 "Expected screen size 2 %ux%u, got %ux%u.\n",
2812 fullscreen_rect
.right
, fullscreen_rect
.bottom
, screen_size2
.cx
, screen_size2
.cy
);
2814 GetWindowRect(window
, &r
);
2815 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2816 s
.left
, s
.top
, s
.right
, s
.bottom
,
2817 r
.left
, r
.top
, r
.right
, r
.bottom
);
2818 GetWindowRect(window2
, &r
);
2819 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2820 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2821 r
.left
, r
.top
, r
.right
, r
.bottom
);
2823 memset(&ddsd
, 0, sizeof(ddsd
));
2824 ddsd
.dwSize
= sizeof(ddsd
);
2825 ddsd
.dwFlags
= DDSD_CAPS
;
2826 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2828 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2829 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2830 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2831 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2832 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2833 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2834 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2835 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2836 IDirectDrawSurface_Release(primary
);
2838 ref
= IDirectDraw2_Release(ddraw
);
2839 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2841 GetWindowRect(window
, &r
);
2842 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2843 s
.left
, s
.top
, s
.right
, s
.bottom
,
2844 r
.left
, r
.top
, r
.right
, r
.bottom
);
2847 expect_messages
= NULL
;
2848 DestroyWindow(window
);
2849 DestroyWindow(window2
);
2850 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2851 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
2854 static void test_coop_level_mode_set_multi(void)
2856 IDirectDraw2
*ddraw1
, *ddraw2
;
2857 UINT orig_w
, orig_h
, w
, h
;
2862 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2863 0, 0, 100, 100, 0, 0, 0, 0);
2864 ddraw1
= create_ddraw();
2865 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
2867 orig_w
= GetSystemMetrics(SM_CXSCREEN
);
2868 orig_h
= GetSystemMetrics(SM_CYSCREEN
);
2870 /* With just a single ddraw object, the display mode is restored on
2872 hr
= set_display_mode(ddraw1
, 800, 600);
2873 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
2875 win_skip("Broken SetDisplayMode(), skipping test.\n");
2876 IDirectDraw2_Release(ddraw1
);
2877 DestroyWindow(window
);
2880 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2881 w
= GetSystemMetrics(SM_CXSCREEN
);
2882 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2883 h
= GetSystemMetrics(SM_CYSCREEN
);
2884 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2886 ref
= IDirectDraw2_Release(ddraw1
);
2887 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2888 w
= GetSystemMetrics(SM_CXSCREEN
);
2889 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2890 h
= GetSystemMetrics(SM_CYSCREEN
);
2891 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2893 /* When there are multiple ddraw objects, the display mode is restored to
2894 * the initial mode, before the first SetDisplayMode() call. */
2895 ddraw1
= create_ddraw();
2896 hr
= set_display_mode(ddraw1
, 800, 600);
2897 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2898 w
= GetSystemMetrics(SM_CXSCREEN
);
2899 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2900 h
= GetSystemMetrics(SM_CYSCREEN
);
2901 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2903 ddraw2
= create_ddraw();
2904 hr
= set_display_mode(ddraw2
, 640, 480);
2905 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2906 w
= GetSystemMetrics(SM_CXSCREEN
);
2907 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2908 h
= GetSystemMetrics(SM_CYSCREEN
);
2909 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2911 ref
= IDirectDraw2_Release(ddraw2
);
2912 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2913 w
= GetSystemMetrics(SM_CXSCREEN
);
2914 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2915 h
= GetSystemMetrics(SM_CYSCREEN
);
2916 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2918 ref
= IDirectDraw2_Release(ddraw1
);
2919 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2920 w
= GetSystemMetrics(SM_CXSCREEN
);
2921 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2922 h
= GetSystemMetrics(SM_CYSCREEN
);
2923 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2925 /* Regardless of release ordering. */
2926 ddraw1
= create_ddraw();
2927 hr
= set_display_mode(ddraw1
, 800, 600);
2928 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2929 w
= GetSystemMetrics(SM_CXSCREEN
);
2930 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2931 h
= GetSystemMetrics(SM_CYSCREEN
);
2932 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2934 ddraw2
= create_ddraw();
2935 hr
= set_display_mode(ddraw2
, 640, 480);
2936 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2937 w
= GetSystemMetrics(SM_CXSCREEN
);
2938 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2939 h
= GetSystemMetrics(SM_CYSCREEN
);
2940 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2942 ref
= IDirectDraw2_Release(ddraw1
);
2943 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2944 w
= GetSystemMetrics(SM_CXSCREEN
);
2945 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2946 h
= GetSystemMetrics(SM_CYSCREEN
);
2947 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2949 ref
= IDirectDraw2_Release(ddraw2
);
2950 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2951 w
= GetSystemMetrics(SM_CXSCREEN
);
2952 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2953 h
= GetSystemMetrics(SM_CYSCREEN
);
2954 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2956 /* But only for ddraw objects that called SetDisplayMode(). */
2957 ddraw1
= create_ddraw();
2958 ddraw2
= create_ddraw();
2959 hr
= set_display_mode(ddraw2
, 640, 480);
2960 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2961 w
= GetSystemMetrics(SM_CXSCREEN
);
2962 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2963 h
= GetSystemMetrics(SM_CYSCREEN
);
2964 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2966 ref
= IDirectDraw2_Release(ddraw1
);
2967 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2968 w
= GetSystemMetrics(SM_CXSCREEN
);
2969 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2970 h
= GetSystemMetrics(SM_CYSCREEN
);
2971 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2973 ref
= IDirectDraw2_Release(ddraw2
);
2974 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2975 w
= GetSystemMetrics(SM_CXSCREEN
);
2976 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2977 h
= GetSystemMetrics(SM_CYSCREEN
);
2978 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2980 /* If there's a ddraw object that's currently in exclusive mode, it blocks
2981 * restoring the display mode. */
2982 ddraw1
= create_ddraw();
2983 hr
= set_display_mode(ddraw1
, 800, 600);
2984 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2985 w
= GetSystemMetrics(SM_CXSCREEN
);
2986 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2987 h
= GetSystemMetrics(SM_CYSCREEN
);
2988 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2990 ddraw2
= create_ddraw();
2991 hr
= set_display_mode(ddraw2
, 640, 480);
2992 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2993 w
= GetSystemMetrics(SM_CXSCREEN
);
2994 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2995 h
= GetSystemMetrics(SM_CYSCREEN
);
2996 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2998 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2999 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3001 ref
= IDirectDraw2_Release(ddraw1
);
3002 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3003 w
= GetSystemMetrics(SM_CXSCREEN
);
3004 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3005 h
= GetSystemMetrics(SM_CYSCREEN
);
3006 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3008 ref
= IDirectDraw2_Release(ddraw2
);
3009 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3010 w
= GetSystemMetrics(SM_CXSCREEN
);
3011 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
3012 h
= GetSystemMetrics(SM_CYSCREEN
);
3013 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
3015 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
3016 ddraw1
= create_ddraw();
3017 hr
= set_display_mode(ddraw1
, 800, 600);
3018 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3019 w
= GetSystemMetrics(SM_CXSCREEN
);
3020 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3021 h
= GetSystemMetrics(SM_CYSCREEN
);
3022 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3024 hr
= IDirectDraw2_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3025 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3027 ddraw2
= create_ddraw();
3028 hr
= set_display_mode(ddraw2
, 640, 480);
3029 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
3031 ref
= IDirectDraw2_Release(ddraw1
);
3032 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3033 w
= GetSystemMetrics(SM_CXSCREEN
);
3034 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
3035 h
= GetSystemMetrics(SM_CYSCREEN
);
3036 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
3038 ref
= IDirectDraw2_Release(ddraw2
);
3039 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3040 w
= GetSystemMetrics(SM_CXSCREEN
);
3041 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
3042 h
= GetSystemMetrics(SM_CYSCREEN
);
3043 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
3045 DestroyWindow(window
);
3048 static void test_initialize(void)
3050 IDirectDraw2
*ddraw
;
3053 ddraw
= create_ddraw();
3054 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3056 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
3057 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
3058 IDirectDraw2_Release(ddraw
);
3061 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw2
, (void **)&ddraw
);
3062 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr
);
3063 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
3064 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
3065 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
3066 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
3067 IDirectDraw2_Release(ddraw
);
3071 static void test_coop_level_surf_create(void)
3073 IDirectDrawSurface
*surface
;
3074 IDirectDraw2
*ddraw
;
3078 ddraw
= create_ddraw();
3079 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3081 memset(&ddsd
, 0, sizeof(ddsd
));
3082 ddsd
.dwSize
= sizeof(ddsd
);
3083 ddsd
.dwFlags
= DDSD_CAPS
;
3084 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3085 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3086 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
3088 IDirectDraw2_Release(ddraw
);
3091 static void test_coop_level_multi_window(void)
3093 HWND window1
, window2
;
3094 IDirectDraw2
*ddraw
;
3097 window1
= CreateWindowA("static", "ddraw_test1", WS_OVERLAPPEDWINDOW
,
3098 0, 0, 640, 480, 0, 0, 0, 0);
3099 window2
= CreateWindowA("static", "ddraw_test2", WS_OVERLAPPEDWINDOW
,
3100 0, 0, 640, 480, 0, 0, 0, 0);
3101 ddraw
= create_ddraw();
3102 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3104 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
3105 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3106 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3107 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3108 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
3109 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
3111 IDirectDraw2_Release(ddraw
);
3112 DestroyWindow(window2
);
3113 DestroyWindow(window1
);
3116 static void test_clear_rect_count(void)
3118 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3119 IDirect3DMaterial2
*white
, *red
, *green
, *blue
;
3120 IDirect3DViewport2
*viewport
;
3121 IDirect3DDevice2
*device
;
3122 IDirectDrawSurface
*rt
;
3123 IDirectDraw2
*ddraw
;
3128 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3129 0, 0, 640, 480, 0, 0, 0, 0);
3130 ddraw
= create_ddraw();
3131 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3132 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3134 skip("Failed to create a 3D device, skipping test.\n");
3135 IDirectDraw2_Release(ddraw
);
3136 DestroyWindow(window
);
3140 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
3141 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3143 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
3144 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
3145 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
3146 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
3148 viewport
= create_viewport(device
, 0, 0, 640, 480);
3149 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
3150 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
3152 viewport_set_background(device
, viewport
, white
);
3153 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
3154 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3155 viewport_set_background(device
, viewport
, red
);
3156 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
3157 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3158 viewport_set_background(device
, viewport
, green
);
3159 hr
= IDirect3DViewport2_Clear(viewport
, 0, NULL
, D3DCLEAR_TARGET
);
3160 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3161 viewport_set_background(device
, viewport
, blue
);
3162 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
3163 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3165 color
= get_surface_color(rt
, 320, 240);
3166 ok(compare_color(color
, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", color
);
3168 IDirectDrawSurface_Release(rt
);
3169 destroy_viewport(device
, viewport
);
3170 destroy_material(white
);
3171 destroy_material(red
);
3172 destroy_material(green
);
3173 destroy_material(blue
);
3174 IDirect3DDevice2_Release(device
);
3175 IDirectDraw2_Release(ddraw
);
3176 DestroyWindow(window
);
3179 static BOOL
test_mode_restored(IDirectDraw2
*ddraw
, HWND window
)
3181 DDSURFACEDESC ddsd1
, ddsd2
;
3184 memset(&ddsd1
, 0, sizeof(ddsd1
));
3185 ddsd1
.dwSize
= sizeof(ddsd1
);
3186 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd1
);
3187 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
3189 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3190 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3191 hr
= set_display_mode(ddraw
, 640, 480);
3192 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3193 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3194 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3196 memset(&ddsd2
, 0, sizeof(ddsd2
));
3197 ddsd2
.dwSize
= sizeof(ddsd2
);
3198 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd2
);
3199 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
3200 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3201 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3203 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
3206 static void test_coop_level_versions(void)
3212 IDirectDrawSurface
*surface
;
3213 IDirectDraw2
*ddraw2
;
3216 window
= CreateWindowA("static", "ddraw_test1", WS_OVERLAPPEDWINDOW
,
3217 0, 0, 640, 480, 0, 0, 0, 0);
3219 ddraw2
= create_ddraw();
3220 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3221 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
3222 restored
= test_mode_restored(ddraw2
, window
);
3223 ok(restored
, "Display mode not restored in new ddraw object\n");
3225 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
3226 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3227 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3229 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3230 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
3231 restored
= test_mode_restored(ddraw2
, window
);
3232 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
3234 /* A successful one does */
3235 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3236 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3237 restored
= test_mode_restored(ddraw2
, window
);
3238 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
3240 IDirectDraw_Release(ddraw
);
3241 IDirectDraw2_Release(ddraw2
);
3243 ddraw2
= create_ddraw();
3244 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3245 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3246 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3248 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
3249 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3250 restored
= test_mode_restored(ddraw2
, window
);
3251 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
3253 IDirectDraw_Release(ddraw
);
3254 IDirectDraw2_Release(ddraw2
);
3256 /* A failing call does not restore the ddraw2+ behavior */
3257 ddraw2
= create_ddraw();
3258 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3259 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3260 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3262 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3263 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3264 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3265 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
3266 restored
= test_mode_restored(ddraw2
, window
);
3267 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
3269 IDirectDraw_Release(ddraw
);
3270 IDirectDraw2_Release(ddraw2
);
3272 /* Neither does a sequence of successful calls with the new interface */
3273 ddraw2
= create_ddraw();
3274 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3275 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3276 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3278 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3279 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3280 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3281 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3282 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
3283 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3285 restored
= test_mode_restored(ddraw2
, window
);
3286 ok(!restored
, "Display mode restored after ddraw1-ddraw2 SetCooperativeLevel() call sequence\n");
3287 IDirectDraw_Release(ddraw
);
3288 IDirectDraw2_Release(ddraw2
);
3290 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
3291 ddraw2
= create_ddraw();
3292 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3293 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3294 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3296 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
3297 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3299 memset(&ddsd
, 0, sizeof(ddsd
));
3300 ddsd
.dwSize
= sizeof(ddsd
);
3301 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
3302 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
3303 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
3304 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3305 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#x.\n", hr
);
3306 IDirectDrawSurface_Release(surface
);
3307 restored
= test_mode_restored(ddraw2
, window
);
3308 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
3310 IDirectDraw_Release(ddraw
);
3311 IDirectDraw2_Release(ddraw2
);
3312 DestroyWindow(window
);
3315 static void test_lighting_interface_versions(void)
3317 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3318 IDirect3DMaterial2
*emissive
, *background
;
3319 IDirect3DViewport2
*viewport
;
3320 IDirect3DDevice2
*device
;
3321 IDirectDrawSurface
*rt
;
3322 IDirectDraw2
*ddraw
;
3326 D3DMATERIALHANDLE mat_handle
;
3330 static D3DVERTEX quad
[] =
3332 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3333 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3334 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3335 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3337 static D3DLVERTEX lquad
[] =
3339 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3340 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3341 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3342 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3344 static D3DTLVERTEX tlquad
[] =
3346 {{ 0.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3347 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3348 {{ 640.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3349 {{ 640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3353 D3DVERTEXTYPE vertextype
;
3355 DWORD d3drs_lighting
, d3drs_specular
;
3361 /* Lighting is enabled when D3DVT_VERTEX is used and D3DDP_DONOTLIGHT is not
3362 * set. D3DVT_VERTEX has diffuse = 0xffffffff and specular = 0x00000000, as
3363 * in later d3d versions */
3364 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, 0, 0x0000ff00},
3365 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, 0, 0x0000ff00},
3366 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3367 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3368 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, 0, 0x0000ff00},
3369 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, 0, 0x0000ff00},
3370 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3371 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3373 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, 0, 0x00ff0000},
3374 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, 0, 0x00ff0000},
3375 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
3376 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
3377 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, 0, 0x00ff8080},
3378 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, 0, 0x00ff8080},
3379 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
3380 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
3382 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, 0, 0x000000ff},
3383 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, 0, 0x000000ff},
3384 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
3385 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
3386 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, 0, 0x008080ff},
3387 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, 0, 0x008080ff},
3388 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
3389 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
3392 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3393 0, 0, 640, 480, 0, 0, 0, 0);
3394 ddraw
= create_ddraw();
3395 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3396 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3398 skip("Failed to create a 3D device, skipping test.\n");
3399 IDirectDraw2_Release(ddraw
);
3400 DestroyWindow(window
);
3404 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
3405 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3407 viewport
= create_viewport(device
, 0, 0, 640, 480);
3408 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
3409 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
3411 emissive
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
3412 hr
= IDirect3DMaterial2_GetHandle(emissive
, device
, &mat_handle
);
3413 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
3414 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
3415 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
3416 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
3417 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#x.\n", hr
);
3419 background
= create_diffuse_material(device
, 0.1f
, 0.1f
, 0.1f
, 0.1f
);
3420 viewport_set_background(device
, viewport
, background
);
3422 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, &rs
);
3423 ok(SUCCEEDED(hr
), "Failed to get specularenable render state, hr %#x.\n", hr
);
3424 ok(rs
== TRUE
, "Initial D3DRENDERSTATE_SPECULARENABLE is %#x, expected TRUE.\n", rs
);
3426 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
3428 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
3429 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3431 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, tests
[i
].d3drs_lighting
);
3432 ok(SUCCEEDED(hr
), "Failed to set lighting render state, hr %#x.\n", hr
);
3433 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
,
3434 tests
[i
].d3drs_specular
);
3435 ok(SUCCEEDED(hr
), "Failed to set specularenable render state, hr %#x.\n", hr
);
3437 hr
= IDirect3DDevice2_BeginScene(device
);
3438 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
3439 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
3440 tests
[i
].vertextype
, tests
[i
].data
, 4, tests
[i
].draw_flags
| D3DDP_WAIT
);
3441 hr
= IDirect3DDevice2_EndScene(device
);
3442 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
3444 color
= get_surface_color(rt
, 320, 240);
3445 ok(compare_color(color
, tests
[i
].color
, 1),
3446 "Got unexpected color 0x%08x, expected 0x%08x, test %u.\n",
3447 color
, tests
[i
].color
, i
);
3450 destroy_material(background
);
3451 destroy_material(emissive
);
3452 IDirectDrawSurface_Release(rt
);
3453 IDirect3DDevice2_Release(device
);
3454 ref
= IDirectDraw2_Release(ddraw
);
3455 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
3456 DestroyWindow(window
);
3462 IDirectDraw2
*ddraw
;
3465 } activateapp_testdata
;
3467 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
3469 if (message
== WM_ACTIVATEAPP
)
3471 if (activateapp_testdata
.ddraw
)
3474 activateapp_testdata
.received
= FALSE
;
3475 hr
= IDirectDraw2_SetCooperativeLevel(activateapp_testdata
.ddraw
,
3476 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
3477 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#x.\n", hr
);
3478 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
3480 activateapp_testdata
.received
= TRUE
;
3483 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
3486 static void test_coop_level_activateapp(void)
3488 IDirectDraw2
*ddraw
;
3493 IDirectDrawSurface
*surface
;
3495 ddraw
= create_ddraw();
3496 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3498 wc
.lpfnWndProc
= activateapp_test_proc
;
3499 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
3500 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3502 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
3503 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
3505 /* Exclusive with window already active. */
3506 SetActiveWindow(window
);
3507 activateapp_testdata
.received
= FALSE
;
3508 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3509 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3510 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
3511 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3512 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3514 /* Exclusive with window not active. */
3515 SetActiveWindow(NULL
);
3516 activateapp_testdata
.received
= FALSE
;
3517 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3518 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3519 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3520 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3521 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3523 /* Normal with window not active, then exclusive with the same window. */
3524 SetActiveWindow(NULL
);
3525 activateapp_testdata
.received
= FALSE
;
3526 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3527 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3528 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
3529 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3530 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3531 /* Except in the first SetCooperativeLevel call, Windows XP randomly does not send
3532 * WM_ACTIVATEAPP. Windows 7 sends the message reliably. Mark the XP behavior broken. */
3533 ok(activateapp_testdata
.received
|| broken(!activateapp_testdata
.received
),
3534 "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3535 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3536 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3538 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
3539 SetActiveWindow(NULL
);
3540 activateapp_testdata
.received
= FALSE
;
3541 activateapp_testdata
.ddraw
= ddraw
;
3542 activateapp_testdata
.window
= window
;
3543 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
3544 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3545 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3546 ok(activateapp_testdata
.received
|| broken(!activateapp_testdata
.received
),
3547 "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3548 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3549 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3551 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
3552 * succeeding. Another switch to exclusive and back to normal is needed to release the
3553 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
3554 * WM_ACTIVATEAPP messages. */
3555 activateapp_testdata
.ddraw
= NULL
;
3556 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3557 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3558 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3559 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3561 /* Setting DDSCL_NORMAL with recursive invocation. */
3562 SetActiveWindow(NULL
);
3563 activateapp_testdata
.received
= FALSE
;
3564 activateapp_testdata
.ddraw
= ddraw
;
3565 activateapp_testdata
.window
= window
;
3566 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
3567 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3568 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3569 ok(activateapp_testdata
.received
|| broken(!activateapp_testdata
.received
),
3570 "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3572 /* DDraw is in exlusive mode now. */
3573 memset(&ddsd
, 0, sizeof(ddsd
));
3574 ddsd
.dwSize
= sizeof(ddsd
);
3575 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
3576 ddsd
.dwBackBufferCount
= 1;
3577 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
3578 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3579 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
3580 IDirectDrawSurface_Release(surface
);
3582 /* Recover again, just to be sure. */
3583 activateapp_testdata
.ddraw
= NULL
;
3584 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3585 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3586 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3587 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3589 DestroyWindow(window
);
3590 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3591 IDirectDraw2_Release(ddraw
);
3594 struct format_support_check
3596 const DDPIXELFORMAT
*format
;
3600 static HRESULT WINAPI
test_unsupported_formats_cb(DDSURFACEDESC
*desc
, void *ctx
)
3602 struct format_support_check
*format
= ctx
;
3604 if (!memcmp(format
->format
, &desc
->ddpfPixelFormat
, sizeof(*format
->format
)))
3606 format
->supported
= TRUE
;
3607 return DDENUMRET_CANCEL
;
3610 return DDENUMRET_OK
;
3613 static void test_unsupported_formats(void)
3616 BOOL expect_success
;
3618 IDirectDraw2
*ddraw
;
3619 IDirect3DDevice2
*device
;
3620 IDirectDrawSurface
*surface
;
3623 DWORD expected_caps
;
3634 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
3635 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
3641 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
3642 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3646 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
3648 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3649 0, 0, 640, 480, 0, 0, 0, 0);
3650 ddraw
= create_ddraw();
3651 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3652 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3654 skip("Failed to create a 3D device, skipping test.\n");
3655 IDirectDraw2_Release(ddraw
);
3656 DestroyWindow(window
);
3660 for (i
= 0; i
< sizeof(formats
) / sizeof(*formats
); i
++)
3662 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
3663 hr
= IDirect3DDevice2_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
3664 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
3666 for (j
= 0; j
< sizeof(caps
) / sizeof(*caps
); j
++)
3668 memset(&ddsd
, 0, sizeof(ddsd
));
3669 ddsd
.dwSize
= sizeof(ddsd
);
3670 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
3671 ddsd
.ddpfPixelFormat
= formats
[i
].fmt
;
3674 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
3676 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
3677 expect_success
= FALSE
;
3679 expect_success
= TRUE
;
3681 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3682 ok(SUCCEEDED(hr
) == expect_success
,
3683 "Got unexpected hr %#x for format %s, caps %#x, expected %s.\n",
3684 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
3688 memset(&ddsd
, 0, sizeof(ddsd
));
3689 ddsd
.dwSize
= sizeof(ddsd
);
3690 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &ddsd
);
3691 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3693 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
3694 expected_caps
= DDSCAPS_VIDEOMEMORY
;
3695 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
3696 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
3697 else if (check
.supported
)
3698 expected_caps
= DDSCAPS_VIDEOMEMORY
;
3700 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
3702 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
3703 "Expected capability %#x, format %s, input cap %#x.\n",
3704 expected_caps
, formats
[i
].name
, caps
[j
]);
3706 IDirectDrawSurface_Release(surface
);
3710 IDirect3DDevice2_Release(device
);
3711 IDirectDraw2_Release(ddraw
);
3712 DestroyWindow(window
);
3715 static void test_rt_caps(void)
3717 PALETTEENTRY palette_entries
[256];
3718 IDirectDrawPalette
*palette
;
3719 IDirect3DDevice2
*device
;
3720 IDirectDraw2
*ddraw
;
3728 static const DDPIXELFORMAT p8_fmt
=
3730 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
3731 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
3736 const DDPIXELFORMAT
*pf
;
3739 HRESULT create_device_hr
;
3741 HRESULT alternative_set_rt_hr
;
3742 BOOL create_may_fail
;
3748 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
3749 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3757 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
3758 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3766 DDSCAPS_OFFSCREENPLAIN
,
3767 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3775 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3776 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3777 D3DERR_SURFACENOTINVIDMEM
,
3784 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3785 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3793 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
3794 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3803 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3812 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3820 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3821 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3822 D3DERR_SURFACENOTINVIDMEM
,
3829 DDSCAPS_SYSTEMMEMORY
,
3830 DDSCAPS_SYSTEMMEMORY
,
3839 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3847 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
3849 DDERR_NOPALETTEATTACHED
,
3856 DDSCAPS_OFFSCREENPLAIN
,
3857 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3865 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3866 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3867 DDERR_NOPALETTEATTACHED
,
3874 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3875 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3883 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
3884 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
3886 DDERR_INVALIDPIXELFORMAT
,
3888 TRUE
/* AMD Evergreen */,
3892 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
3893 ~0U /* AMD Evergreen */,
3895 DDERR_INVALIDPIXELFORMAT
,
3902 ~0U /* AMD Evergreen */,
3910 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
3911 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
3913 DDERR_INVALIDPIXELFORMAT
,
3914 DDERR_INVALIDPIXELFORMAT
,
3915 TRUE
/* Nvidia Kepler */,
3919 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
3920 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
3924 TRUE
/* Nvidia Kepler */,
3928 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3929 0, 0, 640, 480, 0, 0, 0, 0);
3930 ddraw
= create_ddraw();
3931 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3932 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3934 skip("Failed to create a 3D device, skipping test.\n");
3935 IDirectDraw2_Release(ddraw
);
3936 DestroyWindow(window
);
3939 z_depth
= get_device_z_depth(device
);
3940 ok(!!z_depth
, "Failed to get device z depth.\n");
3941 IDirect3DDevice2_Release(device
);
3943 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
3945 skip("D3D interface is not available, skipping test.\n");
3949 memset(palette_entries
, 0, sizeof(palette_entries
));
3950 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
3951 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
3953 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
3955 IDirectDrawSurface
*surface
, *rt
, *expected_rt
, *tmp
;
3956 DDSURFACEDESC surface_desc
;
3957 IDirect3DDevice2
*device
;
3959 memset(&surface_desc
, 0, sizeof(surface_desc
));
3960 surface_desc
.dwSize
= sizeof(surface_desc
);
3961 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
3962 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
3963 if (test_data
[i
].pf
)
3965 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
3966 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
3968 if (test_data
[i
].caps_in
& DDSCAPS_ZBUFFER
)
3970 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
3971 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
3973 surface_desc
.dwWidth
= 640;
3974 surface_desc
.dwHeight
= 480;
3975 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
3976 ok(SUCCEEDED(hr
) || broken(test_data
[i
].create_may_fail
),
3977 "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
3978 i
, test_data
[i
].caps_in
, hr
);
3982 memset(&surface_desc
, 0, sizeof(surface_desc
));
3983 surface_desc
.dwSize
= sizeof(surface_desc
);
3984 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
3985 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
3986 ok(test_data
[i
].caps_out
== ~0U || surface_desc
.ddsCaps
.dwCaps
== test_data
[i
].caps_out
,
3987 "Test %u: Got unexpected caps %#x, expected %#x.\n",
3988 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
3990 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
3991 ok(hr
== test_data
[i
].create_device_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n",
3992 i
, hr
, test_data
[i
].create_device_hr
);
3995 if (hr
== DDERR_NOPALETTEATTACHED
)
3997 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
3998 ok(SUCCEEDED(hr
), "Test %u: Failed to set palette, hr %#x.\n", i
, hr
);
3999 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
4000 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
4001 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
4003 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
4005 IDirectDrawSurface_Release(surface
);
4007 memset(&surface_desc
, 0, sizeof(surface_desc
));
4008 surface_desc
.dwSize
= sizeof(surface_desc
);
4009 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4010 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
4011 surface_desc
.dwWidth
= 640;
4012 surface_desc
.dwHeight
= 480;
4013 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4014 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface, hr %#x.\n", i
, hr
);
4016 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
4017 ok(SUCCEEDED(hr
), "Test %u: Failed to create device, hr %#x.\n", i
, hr
);
4020 memset(&surface_desc
, 0, sizeof(surface_desc
));
4021 surface_desc
.dwSize
= sizeof(surface_desc
);
4022 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4023 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
4024 if (test_data
[i
].pf
)
4026 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
4027 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
4029 if (test_data
[i
].caps_in
& DDSCAPS_ZBUFFER
)
4031 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4032 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
4034 surface_desc
.dwWidth
= 640;
4035 surface_desc
.dwHeight
= 480;
4036 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
4037 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
4038 i
, test_data
[i
].caps_in
, hr
);
4040 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
4041 ok(hr
== test_data
[i
].set_rt_hr
|| broken(hr
== test_data
[i
].alternative_set_rt_hr
),
4042 "Test %u: Got unexpected hr %#x, expected %#x.\n",
4043 i
, hr
, test_data
[i
].set_rt_hr
);
4044 if (SUCCEEDED(hr
) || hr
== DDERR_INVALIDPIXELFORMAT
)
4047 expected_rt
= surface
;
4049 /* It appears the surface is set as render target in this case, but no
4050 * reference is taken. */
4051 if (hr
== DDERR_INVALIDPIXELFORMAT
)
4053 refcount
= IDirectDrawSurface_AddRef(rt
);
4054 ok(refcount
== 2, "Test %u: Got unexpected refcount %u.\n", i
, refcount
);
4057 hr
= IDirect3DDevice2_GetRenderTarget(device
, &tmp
);
4058 ok(SUCCEEDED(hr
), "Test %u: Failed to get render target, hr %#x.\n", i
, hr
);
4059 ok(tmp
== expected_rt
, "Test %u: Got unexpected rt %p.\n", i
, tmp
);
4061 IDirectDrawSurface_Release(tmp
);
4062 IDirectDrawSurface_Release(rt
);
4063 refcount
= IDirect3DDevice2_Release(device
);
4064 ok(refcount
== 0, "Test %u: The device was not properly freed, refcount %u.\n", i
, refcount
);
4065 refcount
= IDirectDrawSurface_Release(surface
);
4066 ok(refcount
== 0, "Test %u: The surface was not properly freed, refcount %u.\n", i
, refcount
);
4069 IDirectDrawPalette_Release(palette
);
4070 IDirect3D2_Release(d3d
);
4073 refcount
= IDirectDraw2_Release(ddraw
);
4074 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4075 DestroyWindow(window
);
4078 static void test_primary_caps(void)
4080 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
4081 IDirectDrawSurface
*surface
;
4082 DDSURFACEDESC surface_desc
;
4083 IDirectDraw2
*ddraw
;
4093 DWORD back_buffer_count
;
4101 DDSCAPS_PRIMARYSURFACE
,
4104 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
4108 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
4115 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
4122 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
4129 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
4136 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
4143 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4150 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4157 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4159 DDERR_NOEXCLUSIVEMODE
,
4163 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4164 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4170 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4171 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4174 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
4177 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4178 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
4184 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4185 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
4192 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4193 0, 0, 640, 480, 0, 0, 0, 0);
4194 ddraw
= create_ddraw();
4195 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4197 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
4199 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
4200 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4202 memset(&surface_desc
, 0, sizeof(surface_desc
));
4203 surface_desc
.dwSize
= sizeof(surface_desc
);
4204 surface_desc
.dwFlags
= DDSD_CAPS
;
4205 if (test_data
[i
].back_buffer_count
!= ~0u)
4206 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
4207 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
4208 surface_desc
.dwBackBufferCount
= test_data
[i
].back_buffer_count
;
4209 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4210 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
4214 memset(&surface_desc
, 0, sizeof(surface_desc
));
4215 surface_desc
.dwSize
= sizeof(surface_desc
);
4216 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
4217 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
4218 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
4219 "Test %u: Got unexpected caps %#x, expected %#x.\n",
4220 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
4222 IDirectDrawSurface_Release(surface
);
4225 refcount
= IDirectDraw2_Release(ddraw
);
4226 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4227 DestroyWindow(window
);
4230 static void test_surface_lock(void)
4232 IDirectDraw2
*ddraw
;
4233 IDirectDrawSurface
*surface
;
4234 IDirect3DDevice2
*device
;
4249 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
4250 "videomemory offscreenplain"
4253 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4254 "systemmemory offscreenplain"
4257 DDSCAPS_PRIMARYSURFACE
,
4261 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
4262 "videomemory texture"
4265 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
4266 "systemmemory texture"
4269 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4278 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4279 0, 0, 640, 480, 0, 0, 0, 0);
4280 ddraw
= create_ddraw();
4281 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4282 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4284 skip("Failed to create a 3D device, skipping test.\n");
4285 IDirectDraw2_Release(ddraw
);
4286 DestroyWindow(window
);
4289 z_depth
= get_device_z_depth(device
);
4290 ok(!!z_depth
, "Failed to get device z depth.\n");
4291 IDirect3DDevice2_Release(device
);
4293 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
4295 memset(&ddsd
, 0, sizeof(ddsd
));
4296 ddsd
.dwSize
= sizeof(ddsd
);
4297 ddsd
.dwFlags
= DDSD_CAPS
;
4298 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
4300 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
4304 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
4306 ddsd
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4307 U2(ddsd
).dwZBufferBitDepth
= z_depth
;
4309 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
4311 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4312 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4314 memset(&ddsd
, 0, sizeof(ddsd
));
4315 ddsd
.dwSize
= sizeof(ddsd
);
4316 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
4317 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4320 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4321 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4324 IDirectDrawSurface_Release(surface
);
4327 refcount
= IDirectDraw2_Release(ddraw
);
4328 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4329 DestroyWindow(window
);
4332 static void test_surface_discard(void)
4334 IDirectDraw2
*ddraw
;
4338 IDirectDrawSurface
*surface
, *primary
;
4347 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, TRUE
},
4348 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
4349 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, TRUE
},
4350 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
4354 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4355 0, 0, 640, 480, 0, 0, 0, 0);
4356 ddraw
= create_ddraw();
4357 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4358 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4359 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4361 memset(&ddsd
, 0, sizeof(ddsd
));
4362 ddsd
.dwSize
= sizeof(ddsd
);
4363 ddsd
.dwFlags
= DDSD_CAPS
;
4364 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4365 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
4367 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
4371 memset(&ddsd
, 0, sizeof(ddsd
));
4372 ddsd
.dwSize
= sizeof(ddsd
);
4373 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4374 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
4377 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4380 skip("Failed to create surface, skipping.\n");
4384 memset(&ddsd
, 0, sizeof(ddsd
));
4385 ddsd
.dwSize
= sizeof(ddsd
);
4386 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
4387 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4388 addr
= ddsd
.lpSurface
;
4389 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4390 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4392 memset(&ddsd
, 0, sizeof(ddsd
));
4393 ddsd
.dwSize
= sizeof(ddsd
);
4394 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
4395 ok(SUCCEEDED(hr
) , "Failed to lock surface, hr %#x.\n", hr
);
4396 discarded
= ddsd
.lpSurface
!= addr
;
4397 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4398 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4400 hr
= IDirectDrawSurface_Blt(primary
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
4401 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
4403 memset(&ddsd
, 0, sizeof(ddsd
));
4404 ddsd
.dwSize
= sizeof(ddsd
);
4405 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
4406 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4407 discarded
|= ddsd
.lpSurface
!= addr
;
4408 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4409 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4411 IDirectDrawSurface_Release(surface
);
4413 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
4414 * AMD r500, evergreen). Windows XP, at least on AMD r200, never changes the pointer. */
4415 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
4418 IDirectDrawSurface_Release(primary
);
4419 IDirectDraw2_Release(ddraw
);
4420 DestroyWindow(window
);
4423 static void test_flip(void)
4425 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
4426 IDirectDrawSurface
*primary
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
4427 DDSCAPS caps
= {DDSCAPS_FLIP
};
4428 DDSURFACEDESC surface_desc
;
4429 BOOL sysmem_primary
;
4430 IDirectDraw2
*ddraw
;
4437 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4438 0, 0, 640, 480, 0, 0, 0, 0);
4439 ddraw
= create_ddraw();
4440 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4442 hr
= set_display_mode(ddraw
, 640, 480);
4443 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
4444 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4445 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4447 memset(&surface_desc
, 0, sizeof(surface_desc
));
4448 surface_desc
.dwSize
= sizeof(surface_desc
);
4449 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
4450 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
4451 surface_desc
.dwBackBufferCount
= 3;
4452 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
4453 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4455 memset(&surface_desc
, 0, sizeof(surface_desc
));
4456 surface_desc
.dwSize
= sizeof(surface_desc
);
4457 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
4458 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4459 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
)
4460 == (DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
),
4461 "Got unexpected caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
4462 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
4464 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &caps
, &backbuffer1
);
4465 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
4466 memset(&surface_desc
, 0, sizeof(surface_desc
));
4467 surface_desc
.dwSize
= sizeof(surface_desc
);
4468 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer1
, &surface_desc
);
4469 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4470 ok(!surface_desc
.dwBackBufferCount
, "Got unexpected back buffer count %u.\n", surface_desc
.dwBackBufferCount
);
4471 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == (DDSCAPS_FLIP
| DDSCAPS_COMPLEX
| DDSCAPS_BACKBUFFER
),
4472 "Got unexpected caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
4474 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
4475 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
4476 memset(&surface_desc
, 0, sizeof(surface_desc
));
4477 surface_desc
.dwSize
= sizeof(surface_desc
);
4478 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer2
, &surface_desc
);
4479 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4480 ok(!surface_desc
.dwBackBufferCount
, "Got unexpected back buffer count %u.\n", surface_desc
.dwBackBufferCount
);
4481 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == (DDSCAPS_FLIP
| DDSCAPS_COMPLEX
),
4482 "Got unexpected caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
4484 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
4485 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
4486 memset(&surface_desc
, 0, sizeof(surface_desc
));
4487 surface_desc
.dwSize
= sizeof(surface_desc
);
4488 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer3
, &surface_desc
);
4489 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4490 ok(!surface_desc
.dwBackBufferCount
, "Got unexpected back buffer count %u.\n", surface_desc
.dwBackBufferCount
);
4491 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == (DDSCAPS_FLIP
| DDSCAPS_COMPLEX
),
4492 "Got unexpected caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
4494 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
4495 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
4496 ok(surface
== primary
, "Got unexpected surface %p, expected %p.\n", surface
, primary
);
4497 IDirectDrawSurface_Release(surface
);
4499 memset(&surface_desc
, 0, sizeof(surface_desc
));
4500 surface_desc
.dwSize
= sizeof(surface_desc
);
4501 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4502 surface_desc
.ddsCaps
.dwCaps
= 0;
4503 surface_desc
.dwWidth
= 640;
4504 surface_desc
.dwHeight
= 480;
4505 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4506 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4507 hr
= IDirectDrawSurface_Flip(primary
, surface
, DDFLIP_WAIT
);
4508 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
4509 IDirectDrawSurface_Release(surface
);
4511 hr
= IDirectDrawSurface_Flip(primary
, primary
, DDFLIP_WAIT
);
4512 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
4513 hr
= IDirectDrawSurface_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
4514 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
4515 hr
= IDirectDrawSurface_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
4516 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
4517 hr
= IDirectDrawSurface_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
4518 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
4520 memset(&fx
, 0, sizeof(fx
));
4521 fx
.dwSize
= sizeof(fx
);
4522 U5(fx
).dwFillColor
= 0xffff0000;
4523 hr
= IDirectDrawSurface_Blt(backbuffer1
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4524 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4525 U5(fx
).dwFillColor
= 0xff00ff00;
4526 hr
= IDirectDrawSurface_Blt(backbuffer2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4527 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4528 U5(fx
).dwFillColor
= 0xff0000ff;
4529 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4530 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4532 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
4533 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
4534 color
= get_surface_color(backbuffer1
, 320, 240);
4535 /* The testbot seems to just copy the contents of one surface to all the
4536 * others, instead of properly flipping. */
4537 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
4538 "Got unexpected color 0x%08x.\n", color
);
4539 color
= get_surface_color(backbuffer2
, 320, 240);
4540 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
4541 U5(fx
).dwFillColor
= 0xffff0000;
4542 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4543 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4545 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
4546 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
4547 color
= get_surface_color(backbuffer1
, 320, 240);
4548 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
4549 "Got unexpected color 0x%08x.\n", color
);
4550 color
= get_surface_color(backbuffer2
, 320, 240);
4551 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
4552 U5(fx
).dwFillColor
= 0xff00ff00;
4553 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4554 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4556 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
4557 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
4558 color
= get_surface_color(backbuffer1
, 320, 240);
4559 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
4560 "Got unexpected color 0x%08x.\n", color
);
4561 color
= get_surface_color(backbuffer2
, 320, 240);
4562 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
4563 U5(fx
).dwFillColor
= 0xff0000ff;
4564 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4565 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4567 hr
= IDirectDrawSurface_Flip(primary
, backbuffer1
, DDFLIP_WAIT
);
4568 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
4569 color
= get_surface_color(backbuffer2
, 320, 240);
4570 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
4571 "Got unexpected color 0x%08x.\n", color
);
4572 color
= get_surface_color(backbuffer3
, 320, 240);
4573 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
4574 U5(fx
).dwFillColor
= 0xffff0000;
4575 hr
= IDirectDrawSurface_Blt(backbuffer1
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4576 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4578 hr
= IDirectDrawSurface_Flip(primary
, backbuffer2
, DDFLIP_WAIT
);
4579 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
4580 color
= get_surface_color(backbuffer1
, 320, 240);
4581 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
4582 color
= get_surface_color(backbuffer3
, 320, 240);
4583 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
4584 "Got unexpected color 0x%08x.\n", color
);
4585 U5(fx
).dwFillColor
= 0xff00ff00;
4586 hr
= IDirectDrawSurface_Blt(backbuffer2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4587 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
4589 hr
= IDirectDrawSurface_Flip(primary
, backbuffer3
, DDFLIP_WAIT
);
4590 ok(SUCCEEDED(hr
), "Failed to flip, hr %#x.\n", hr
);
4591 color
= get_surface_color(backbuffer1
, 320, 240);
4592 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
4593 "Got unexpected color 0x%08x.\n", color
);
4594 color
= get_surface_color(backbuffer2
, 320, 240);
4595 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
4597 IDirectDrawSurface_Release(backbuffer3
);
4598 IDirectDrawSurface_Release(backbuffer2
);
4599 IDirectDrawSurface_Release(backbuffer1
);
4600 IDirectDrawSurface_Release(primary
);
4601 refcount
= IDirectDraw2_Release(ddraw
);
4602 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4603 DestroyWindow(window
);
4606 static void reset_ddsd(DDSURFACEDESC
*ddsd
)
4608 memset(ddsd
, 0, sizeof(*ddsd
));
4609 ddsd
->dwSize
= sizeof(*ddsd
);
4612 static void test_set_surface_desc(void)
4614 IDirectDraw2
*ddraw
;
4618 IDirectDrawSurface
*surface
;
4619 IDirectDrawSurface3
*surface3
;
4629 invalid_caps_tests
[] =
4631 {DDSCAPS_VIDEOMEMORY
, FALSE
, "videomemory plain"},
4632 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, TRUE
, "systemmemory texture"},
4633 {DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
, FALSE
, "systemmemory primary"},
4636 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4637 0, 0, 640, 480, 0, 0, 0, 0);
4638 ddraw
= create_ddraw();
4639 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4640 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4641 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4644 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
4647 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
4648 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4649 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
4650 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
4651 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
4652 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
4653 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
4655 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4656 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4658 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
4659 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
4660 IDirectDrawSurface_Release(surface
);
4663 ddsd
.dwFlags
= DDSD_LPSURFACE
;
4664 ddsd
.lpSurface
= data
;
4665 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4666 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4668 /* Redundantly setting the same lpSurface is not an error. */
4669 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4670 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4671 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
4672 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4673 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
4674 ok(ddsd
.lpSurface
== NULL
, "lpSurface is %p, expected NULL.\n", ddsd
.lpSurface
);
4676 hr
= IDirectDrawSurface3_Lock(surface3
, NULL
, &ddsd
, 0, NULL
);
4677 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4678 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
4679 ok(ddsd
.lpSurface
== data
, "lpSurface is %p, expected %p.\n", data
, data
);
4680 hr
= IDirectDrawSurface3_Unlock(surface3
, NULL
);
4681 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4684 ddsd
.dwFlags
= DDSD_LPSURFACE
;
4685 ddsd
.lpSurface
= data
;
4686 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 1);
4687 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with flags=1 returned %#x.\n", hr
);
4689 ddsd
.lpSurface
= NULL
;
4690 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4691 ok(hr
== DDERR_INVALIDPARAMS
, "Setting lpSurface=NULL returned %#x.\n", hr
);
4693 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, NULL
, 0);
4694 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with NULL desc returned %#x.\n", hr
);
4696 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
4697 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4698 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
4699 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
4701 /* Setting the caps is an error. This also means the original description cannot be reapplied. */
4702 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4703 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the original desc returned %#x.\n", hr
);
4705 ddsd
.dwFlags
= DDSD_CAPS
;
4706 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4707 ok(hr
== DDERR_INVALIDPARAMS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
4709 /* dwCaps = 0 is allowed, but ignored. */
4710 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_LPSURFACE
;
4711 ddsd
.lpSurface
= data
;
4712 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4713 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
4714 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
4715 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4716 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
4717 ddsd
.ddsCaps
.dwCaps
= 0;
4718 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4719 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4721 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
4722 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4723 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
4724 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
4726 /* Setting the height is allowed, but it cannot be set to 0, and only if LPSURFACE is set too. */
4728 ddsd
.dwFlags
= DDSD_HEIGHT
;
4730 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4731 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height without lpSurface returned %#x.\n", hr
);
4733 ddsd
.lpSurface
= data
;
4734 ddsd
.dwFlags
= DDSD_HEIGHT
| DDSD_LPSURFACE
;
4735 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4736 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4739 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4740 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height=0 returned %#x.\n", hr
);
4743 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
4744 ok(SUCCEEDED(hr
), "GetSurfaceDesc failed, hr %#x.\n", hr
);
4745 ok(ddsd
.dwWidth
== 8, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
4746 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
4748 /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0. */
4750 ddsd
.dwFlags
= DDSD_PITCH
;
4751 U1(ddsd
).lPitch
= 8 * 4;
4752 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4753 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch without lpSurface or width returned %#x.\n", hr
);
4755 ddsd
.dwFlags
= DDSD_WIDTH
;
4757 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4758 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width without lpSurface or pitch returned %#x.\n", hr
);
4760 ddsd
.dwFlags
= DDSD_PITCH
| DDSD_LPSURFACE
;
4761 ddsd
.lpSurface
= data
;
4762 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4763 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch and lpSurface without width returned %#x.\n", hr
);
4765 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_LPSURFACE
;
4766 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4767 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width and lpSurface without pitch returned %#x.\n", hr
);
4769 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
4770 U1(ddsd
).lPitch
= 16 * 4;
4772 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4773 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4776 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
4777 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4778 ok(ddsd
.dwWidth
== 16, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
4779 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
4780 ok(U1(ddsd
).lPitch
== 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %u.\n", U1(ddsd
).lPitch
);
4782 /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise.
4784 * VMware rejects those calls, but all real drivers accept it. Mark the VMware behavior broken. */
4785 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
4786 U1(ddsd
).lPitch
= 4 * 4;
4787 ddsd
.lpSurface
= data
;
4788 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4789 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
4791 U1(ddsd
).lPitch
= 4;
4792 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4793 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
4795 U1(ddsd
).lPitch
= 16 * 4 + 1;
4796 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4797 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
4799 U1(ddsd
).lPitch
= 16 * 4 + 3;
4800 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4801 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
4803 U1(ddsd
).lPitch
= -4;
4804 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4805 ok(hr
== DDERR_INVALIDPARAMS
, "Setting negative pitch returned %#x.\n", hr
);
4807 U1(ddsd
).lPitch
= 16 * 4;
4808 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4809 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4812 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
4813 U1(ddsd
).lPitch
= 0;
4815 ddsd
.lpSurface
= data
;
4816 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4817 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero pitch returned %#x.\n", hr
);
4819 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
4820 U1(ddsd
).lPitch
= 16 * 4;
4822 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4823 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero width returned %#x.\n", hr
);
4825 /* Setting the pixelformat without LPSURFACE is an error, but with LPSURFACE it works. */
4826 ddsd
.dwFlags
= DDSD_PIXELFORMAT
;
4827 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
4828 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4829 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
4830 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
4831 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
4832 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
4833 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4834 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the pixel format returned %#x.\n", hr
);
4836 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
4837 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4838 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4840 /* Can't set color keys. */
4842 ddsd
.dwFlags
= DDSD_CKSRCBLT
;
4843 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff0000;
4844 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff0000;
4845 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4846 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
4848 ddsd
.dwFlags
= DDSD_CKSRCBLT
| DDSD_LPSURFACE
;
4849 ddsd
.lpSurface
= data
;
4850 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4851 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
4853 IDirectDrawSurface3_Release(surface3
);
4855 /* SetSurfaceDesc needs systemmemory surfaces.
4857 * As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing DDSD_LINEARSIZE is moot. */
4858 for (i
= 0; i
< sizeof(invalid_caps_tests
) / sizeof(*invalid_caps_tests
); i
++)
4861 ddsd
.dwFlags
= DDSD_CAPS
;
4862 ddsd
.ddsCaps
.dwCaps
= invalid_caps_tests
[i
].caps
;
4863 if (!(invalid_caps_tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
4865 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
4868 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
4869 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4870 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
4871 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
4872 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
4873 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
4876 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4877 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
, "Failed to create surface, hr %#x.\n", hr
);
4880 skip("Cannot create a %s surface, skipping vidmem SetSurfaceDesc test.\n",
4881 invalid_caps_tests
[i
].name
);
4884 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
4885 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
4886 IDirectDrawSurface_Release(surface
);
4889 ddsd
.dwFlags
= DDSD_LPSURFACE
;
4890 ddsd
.lpSurface
= data
;
4891 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4892 if (invalid_caps_tests
[i
].supported
)
4894 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4898 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
4899 invalid_caps_tests
[i
].name
, hr
);
4901 /* Check priority of error conditions. */
4902 ddsd
.dwFlags
= DDSD_WIDTH
;
4903 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4904 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
4905 invalid_caps_tests
[i
].name
, hr
);
4908 IDirectDrawSurface3_Release(surface3
);
4912 ref
= IDirectDraw2_Release(ddraw
);
4913 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
4914 DestroyWindow(window
);
4917 static void test_user_memory_getdc(void)
4919 IDirectDraw2
*ddraw
;
4923 IDirectDrawSurface
*surface
;
4924 IDirectDrawSurface3
*surface3
;
4930 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4931 0, 0, 640, 480, 0, 0, 0, 0);
4932 ddraw
= create_ddraw();
4933 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4935 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4936 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4939 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
4942 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
4943 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4944 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
4945 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
4946 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
4947 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
4948 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
4949 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4950 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4952 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
4953 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
4954 IDirectDrawSurface_Release(surface
);
4956 memset(data
, 0xaa, sizeof(data
));
4958 ddsd
.dwFlags
= DDSD_LPSURFACE
;
4959 ddsd
.lpSurface
= data
;
4960 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4961 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4963 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
4964 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
4965 BitBlt(dc
, 0, 0, 16, 8, NULL
, 0, 0, WHITENESS
);
4966 BitBlt(dc
, 0, 8, 16, 8, NULL
, 0, 0, BLACKNESS
);
4967 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
4968 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
4970 ok(data
[0][0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data
[0][0]);
4971 ok(data
[15][15] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data
[15][15]);
4973 ddsd
.dwFlags
= DDSD_LPSURFACE
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
;
4974 ddsd
.lpSurface
= data
;
4977 U1(ddsd
).lPitch
= sizeof(*data
);
4978 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
4979 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
4981 memset(data
, 0xaa, sizeof(data
));
4982 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
4983 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
4984 BitBlt(dc
, 0, 0, 4, 8, NULL
, 0, 0, BLACKNESS
);
4985 BitBlt(dc
, 1, 1, 2, 2, NULL
, 0, 0, WHITENESS
);
4986 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
4987 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
4989 for (y
= 0; y
< 4; y
++)
4991 for (x
= 0; x
< 4; x
++)
4993 if ((x
== 1 || x
== 2) && (y
== 1 || y
== 2))
4994 ok(data
[y
][x
] == 0xffffffff, "Expected color 0xffffffff on position %ux%u, got %#x.\n",
4997 ok(data
[y
][x
] == 0x00000000, "Expected color 0xaaaaaaaa on position %ux%u, got %#x.\n",
5001 ok(data
[0][5] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 5x0, got %#x.\n",
5003 ok(data
[7][3] == 0x00000000, "Expected color 0x00000000 on position 3x7, got %#x.\n",
5005 ok(data
[7][4] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 4x7, got %#x.\n",
5007 ok(data
[8][0] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 0x8, got %#x.\n",
5010 IDirectDrawSurface3_Release(surface3
);
5011 ref
= IDirectDraw2_Release(ddraw
);
5012 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
5013 DestroyWindow(window
);
5016 static void test_sysmem_overlay(void)
5018 IDirectDraw2
*ddraw
;
5022 IDirectDrawSurface
*surface
;
5025 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5026 0, 0, 640, 480, 0, 0, 0, 0);
5027 ddraw
= create_ddraw();
5028 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5030 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5031 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5034 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
5037 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
5038 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5039 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5040 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5041 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5042 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5043 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5044 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5045 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#x.\n", hr
);
5047 ref
= IDirectDraw2_Release(ddraw
);
5048 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
5049 DestroyWindow(window
);
5052 static void test_primary_palette(void)
5054 DDSCAPS surface_caps
= {DDSCAPS_FLIP
};
5055 IDirectDrawSurface
*primary
, *backbuffer
;
5056 PALETTEENTRY palette_entries
[256];
5057 IDirectDrawPalette
*palette
, *tmp
;
5058 DDSURFACEDESC surface_desc
;
5059 IDirectDraw2
*ddraw
;
5065 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5066 0, 0, 640, 480, 0, 0, 0, 0);
5067 ddraw
= create_ddraw();
5068 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5069 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
5071 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
5072 IDirectDraw2_Release(ddraw
);
5073 DestroyWindow(window
);
5076 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5077 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5079 memset(&surface_desc
, 0, sizeof(surface_desc
));
5080 surface_desc
.dwSize
= sizeof(surface_desc
);
5081 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
5082 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
5083 surface_desc
.dwBackBufferCount
= 1;
5084 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
5085 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5086 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
5087 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
5089 memset(palette_entries
, 0, sizeof(palette_entries
));
5090 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
5091 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
5092 refcount
= get_refcount((IUnknown
*)palette
);
5093 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5095 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5096 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
5097 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
5099 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
5100 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5102 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
5103 * and is generally somewhat broken with respect to 8 bpp / palette
5105 if (SUCCEEDED(IDirectDrawSurface_GetPalette(backbuffer
, &tmp
)))
5107 win_skip("Broken palette handling detected, skipping tests.\n");
5108 IDirectDrawPalette_Release(tmp
);
5109 IDirectDrawPalette_Release(palette
);
5110 /* The Windows 8 testbot keeps extra references to the primary and
5111 * backbuffer while in 8 bpp mode. */
5112 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
5113 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
5117 refcount
= get_refcount((IUnknown
*)palette
);
5118 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5120 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5121 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
5122 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
5123 "Got unexpected palette caps %#x.\n", palette_caps
);
5125 hr
= IDirectDrawSurface_SetPalette(primary
, NULL
);
5126 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5127 refcount
= get_refcount((IUnknown
*)palette
);
5128 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5130 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5131 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
5132 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
5134 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
5135 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5136 refcount
= get_refcount((IUnknown
*)palette
);
5137 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5139 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
5140 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
5141 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
5142 IDirectDrawPalette_Release(tmp
);
5143 hr
= IDirectDrawSurface_GetPalette(backbuffer
, &tmp
);
5144 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
5146 refcount
= IDirectDrawPalette_Release(palette
);
5147 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5148 refcount
= IDirectDrawPalette_Release(palette
);
5149 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5151 /* Note that this only seems to work when the palette is attached to the
5152 * primary surface. When attached to a regular surface, attempting to get
5153 * the palette here will cause an access violation. */
5154 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
5155 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
5158 refcount
= IDirectDrawSurface_Release(backbuffer
);
5159 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5160 refcount
= IDirectDrawSurface_Release(primary
);
5161 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5162 refcount
= IDirectDraw2_Release(ddraw
);
5163 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5164 DestroyWindow(window
);
5167 static HRESULT WINAPI
surface_counter(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
5169 UINT
*surface_count
= context
;
5172 IDirectDrawSurface_Release(surface
);
5174 return DDENUMRET_OK
;
5177 static void test_surface_attachment(void)
5179 IDirectDrawSurface
*surface1
, *surface2
, *surface3
, *surface4
;
5180 DDSCAPS caps
= {DDSCAPS_TEXTURE
};
5181 DDSURFACEDESC surface_desc
;
5182 IDirectDraw2
*ddraw
;
5188 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5189 0, 0, 640, 480, 0, 0, 0, 0);
5190 ddraw
= create_ddraw();
5191 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5192 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5193 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5195 memset(&surface_desc
, 0, sizeof(surface_desc
));
5196 surface_desc
.dwSize
= sizeof(surface_desc
);
5197 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
5198 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
5199 U2(surface_desc
).dwMipMapCount
= 3;
5200 surface_desc
.dwWidth
= 128;
5201 surface_desc
.dwHeight
= 128;
5202 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5203 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5205 hr
= IDirectDrawSurface_GetAttachedSurface(surface1
, &caps
, &surface2
);
5206 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
5207 hr
= IDirectDrawSurface_GetAttachedSurface(surface2
, &caps
, &surface3
);
5208 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
5209 hr
= IDirectDrawSurface_GetAttachedSurface(surface3
, &caps
, &surface4
);
5210 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
5213 IDirectDrawSurface_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
5214 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
5216 IDirectDrawSurface_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
5217 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
5219 IDirectDrawSurface_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
5220 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
5222 memset(&surface_desc
, 0, sizeof(surface_desc
));
5223 surface_desc
.dwSize
= sizeof(surface_desc
);
5224 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5225 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5226 surface_desc
.dwWidth
= 16;
5227 surface_desc
.dwHeight
= 16;
5228 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5229 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5231 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
5232 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5233 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5234 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5235 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
5236 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5237 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
5238 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5239 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
5240 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5241 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
5242 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5244 IDirectDrawSurface_Release(surface4
);
5246 memset(&surface_desc
, 0, sizeof(surface_desc
));
5247 surface_desc
.dwSize
= sizeof(surface_desc
);
5248 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5249 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5250 surface_desc
.dwWidth
= 16;
5251 surface_desc
.dwHeight
= 16;
5252 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5253 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5255 if (SUCCEEDED(hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
)))
5257 skip("Running on refrast, skipping some tests.\n");
5258 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface4
);
5259 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5263 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5264 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5265 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5266 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
5267 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5268 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
5269 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5270 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
5271 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5272 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
5273 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5276 IDirectDrawSurface_Release(surface4
);
5277 IDirectDrawSurface_Release(surface3
);
5278 IDirectDrawSurface_Release(surface2
);
5279 IDirectDrawSurface_Release(surface1
);
5281 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5282 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5284 /* Try a single primary and two offscreen plain surfaces. */
5285 memset(&surface_desc
, 0, sizeof(surface_desc
));
5286 surface_desc
.dwSize
= sizeof(surface_desc
);
5287 surface_desc
.dwFlags
= DDSD_CAPS
;
5288 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
5289 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5290 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5292 memset(&surface_desc
, 0, sizeof(surface_desc
));
5293 surface_desc
.dwSize
= sizeof(surface_desc
);
5294 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5295 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5296 surface_desc
.dwWidth
= GetSystemMetrics(SM_CXSCREEN
);
5297 surface_desc
.dwHeight
= GetSystemMetrics(SM_CYSCREEN
);
5298 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
5299 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5301 memset(&surface_desc
, 0, sizeof(surface_desc
));
5302 surface_desc
.dwSize
= sizeof(surface_desc
);
5303 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5304 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5305 surface_desc
.dwWidth
= GetSystemMetrics(SM_CXSCREEN
);
5306 surface_desc
.dwHeight
= GetSystemMetrics(SM_CYSCREEN
);
5307 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
5308 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5310 /* This one has a different size. */
5311 memset(&surface_desc
, 0, sizeof(surface_desc
));
5312 surface_desc
.dwSize
= sizeof(surface_desc
);
5313 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5314 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5315 surface_desc
.dwWidth
= 128;
5316 surface_desc
.dwHeight
= 128;
5317 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5318 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5320 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5321 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5322 /* Try the reverse without detaching first. */
5323 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
5324 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
5325 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5326 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5328 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
5329 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5330 /* Try to detach reversed. */
5331 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5332 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5333 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface1
);
5334 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5336 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface3
);
5337 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5338 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface3
);
5339 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5341 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
5342 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5343 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5344 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5346 IDirectDrawSurface_Release(surface4
);
5347 IDirectDrawSurface_Release(surface3
);
5348 IDirectDrawSurface_Release(surface2
);
5349 IDirectDrawSurface_Release(surface1
);
5351 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
5352 memset(&surface_desc
, 0, sizeof(surface_desc
));
5353 surface_desc
.dwSize
= sizeof(surface_desc
);
5354 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5355 surface_desc
.dwWidth
= 64;
5356 surface_desc
.dwHeight
= 64;
5357 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
5358 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5359 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
5360 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
5361 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
5362 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
5363 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
5364 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5365 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5366 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
5367 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5369 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
5370 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
5371 U1(surface_desc
.ddpfPixelFormat
).dwZBufferBitDepth
= 16;
5372 U3(surface_desc
.ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
5373 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
5374 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5376 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5377 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5378 refcount
= get_refcount((IUnknown
*)surface2
);
5379 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5380 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5381 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
5383 /* Attaching while already attached to other surface. */
5384 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface2
);
5385 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5386 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface3
, 0, surface2
);
5387 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5388 IDirectDrawSurface_Release(surface3
);
5390 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5391 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5392 refcount
= get_refcount((IUnknown
*)surface2
);
5393 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5395 /* Automatic detachment on release. */
5396 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5397 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5398 refcount
= get_refcount((IUnknown
*)surface2
);
5399 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5400 refcount
= IDirectDrawSurface_Release(surface1
);
5401 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5402 refcount
= IDirectDrawSurface_Release(surface2
);
5403 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5404 refcount
= IDirectDraw2_Release(ddraw
);
5405 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5406 DestroyWindow(window
);
5409 static void test_pixel_format(void)
5411 HWND window
, window2
= NULL
;
5412 HDC hdc
, hdc2
= NULL
;
5414 int format
, test_format
;
5415 PIXELFORMATDESCRIPTOR pfd
;
5416 IDirectDraw2
*ddraw
= NULL
;
5417 IDirectDrawClipper
*clipper
= NULL
;
5419 IDirectDrawSurface
*primary
= NULL
;
5423 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
5424 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
5427 skip("Failed to create window\n");
5431 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
5432 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
5434 hdc
= GetDC(window
);
5437 skip("Failed to get DC\n");
5442 hdc2
= GetDC(window2
);
5444 gl
= LoadLibraryA("opengl32.dll");
5445 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
5447 format
= GetPixelFormat(hdc
);
5448 ok(format
== 0, "new window has pixel format %d\n", format
);
5450 ZeroMemory(&pfd
, sizeof(pfd
));
5451 pfd
.nSize
= sizeof(pfd
);
5453 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
5454 pfd
.iPixelType
= PFD_TYPE_RGBA
;
5455 pfd
.iLayerType
= PFD_MAIN_PLANE
;
5456 format
= ChoosePixelFormat(hdc
, &pfd
);
5459 skip("no pixel format available\n");
5463 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
5465 skip("failed to set pixel format\n");
5469 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
5471 skip("failed to set pixel format on second window\n");
5474 ReleaseDC(window2
, hdc2
);
5479 ddraw
= create_ddraw();
5480 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5482 test_format
= GetPixelFormat(hdc
);
5483 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5485 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5488 skip("Failed to set cooperative level, hr %#x.\n", hr
);
5492 test_format
= GetPixelFormat(hdc
);
5493 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5497 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
5498 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
5499 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
5500 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
5502 test_format
= GetPixelFormat(hdc
);
5503 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5505 test_format
= GetPixelFormat(hdc2
);
5506 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5509 memset(&ddsd
, 0, sizeof(ddsd
));
5510 ddsd
.dwSize
= sizeof(ddsd
);
5511 ddsd
.dwFlags
= DDSD_CAPS
;
5512 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
5514 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
5515 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
5517 test_format
= GetPixelFormat(hdc
);
5518 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5522 test_format
= GetPixelFormat(hdc2
);
5523 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5528 hr
= IDirectDrawSurface2_SetClipper(primary
, clipper
);
5529 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
5531 test_format
= GetPixelFormat(hdc
);
5532 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5534 test_format
= GetPixelFormat(hdc2
);
5535 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5538 memset(&fx
, 0, sizeof(fx
));
5539 fx
.dwSize
= sizeof(fx
);
5540 hr
= IDirectDrawSurface2_Blt(primary
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
5541 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
5543 test_format
= GetPixelFormat(hdc
);
5544 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5548 test_format
= GetPixelFormat(hdc2
);
5549 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5553 if (primary
) IDirectDrawSurface2_Release(primary
);
5554 if (clipper
) IDirectDrawClipper_Release(clipper
);
5555 if (ddraw
) IDirectDraw2_Release(ddraw
);
5556 if (gl
) FreeLibrary(gl
);
5557 if (hdc
) ReleaseDC(window
, hdc
);
5558 if (hdc2
) ReleaseDC(window2
, hdc2
);
5559 if (window
) DestroyWindow(window
);
5560 if (window2
) DestroyWindow(window2
);
5563 static void test_create_surface_pitch(void)
5565 IDirectDrawSurface
*surface
;
5566 DDSURFACEDESC surface_desc
;
5567 IDirectDraw2
*ddraw
;
5586 {DDSCAPS_VIDEOMEMORY
, 0, 0, DD_OK
,
5587 DDSD_PITCH
, 0x100, 0x100},
5588 {DDSCAPS_VIDEOMEMORY
, DDSD_PITCH
, 0x104, DD_OK
,
5589 DDSD_PITCH
, 0x100, 0x100},
5590 {DDSCAPS_VIDEOMEMORY
, DDSD_PITCH
, 0x0f8, DD_OK
,
5591 DDSD_PITCH
, 0x100, 0x100},
5592 {DDSCAPS_VIDEOMEMORY
, DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
5594 {DDSCAPS_SYSTEMMEMORY
, 0, 0, DD_OK
,
5595 DDSD_PITCH
, 0x100, 0x0fc},
5596 {DDSCAPS_SYSTEMMEMORY
, DDSD_PITCH
, 0x104, DD_OK
,
5597 DDSD_PITCH
, 0x100, 0x0fc},
5598 {DDSCAPS_SYSTEMMEMORY
, DDSD_PITCH
, 0x0f8, DD_OK
,
5599 DDSD_PITCH
, 0x100, 0x0fc},
5600 {DDSCAPS_SYSTEMMEMORY
, DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
5601 DDSD_PITCH
, 0x100, 0x0fc},
5602 {DDSCAPS_SYSTEMMEMORY
, DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
5604 {DDSCAPS_SYSTEMMEMORY
, DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
5607 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
5609 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5610 0, 0, 640, 480, 0, 0, 0, 0);
5611 ddraw
= create_ddraw();
5612 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5613 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5614 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5616 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((63 * 4) + 8) * 63);
5618 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
5620 memset(&surface_desc
, 0, sizeof(surface_desc
));
5621 surface_desc
.dwSize
= sizeof(surface_desc
);
5622 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
5623 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| test_data
[i
].placement
;
5624 surface_desc
.dwWidth
= 63;
5625 surface_desc
.dwHeight
= 63;
5626 U1(surface_desc
).lPitch
= test_data
[i
].pitch_in
;
5627 surface_desc
.lpSurface
= mem
;
5628 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5629 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5630 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5631 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5632 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5633 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5634 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5635 ok(hr
== test_data
[i
].hr
|| (test_data
[i
].placement
== DDSCAPS_VIDEOMEMORY
&& hr
== DDERR_NODIRECTDRAWHW
),
5636 "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
5640 memset(&surface_desc
, 0, sizeof(surface_desc
));
5641 surface_desc
.dwSize
= sizeof(surface_desc
);
5642 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
5643 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
5644 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
5645 "Test %u: Got unexpected flags %#x, expected %#x.\n",
5646 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
5647 if (sizeof(void *) != sizeof(DWORD
) && test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
5648 todo_wine
ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out64
,
5649 "Test %u: Got unexpected pitch %u, expected %u.\n",
5650 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out64
);
5652 ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out32
,
5653 "Test %u: Got unexpected pitch %u, expected %u.\n",
5654 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out32
);
5656 IDirectDrawSurface_Release(surface
);
5659 HeapFree(GetProcessHeap(), 0, mem
);
5660 refcount
= IDirectDraw2_Release(ddraw
);
5661 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5662 DestroyWindow(window
);
5665 static void test_mipmap_lock(void)
5667 IDirectDrawSurface
*surface1
;
5668 IDirectDrawSurface2
*surface
, *surface2
;
5669 DDSURFACEDESC surface_desc
;
5670 IDirectDraw2
*ddraw
;
5674 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
5677 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5678 0, 0, 640, 480, 0, 0, 0, 0);
5679 ddraw
= create_ddraw();
5680 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5681 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5682 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5684 memset(&hal_caps
, 0, sizeof(hal_caps
));
5685 hal_caps
.dwSize
= sizeof(hal_caps
);
5686 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
5687 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
5688 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
5690 skip("Mipmapped textures not supported, skipping mipmap lock test.\n");
5691 IDirectDraw2_Release(ddraw
);
5692 DestroyWindow(window
);
5696 memset(&surface_desc
, 0, sizeof(surface_desc
));
5697 surface_desc
.dwSize
= sizeof(surface_desc
);
5698 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
5699 surface_desc
.dwWidth
= 4;
5700 surface_desc
.dwHeight
= 4;
5701 U2(surface_desc
).dwMipMapCount
= 2;
5702 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
5703 | DDSCAPS_SYSTEMMEMORY
;
5704 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5705 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5707 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
5708 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr
);
5709 IDirectDrawSurface_Release(surface1
);
5710 hr
= IDirectDrawSurface2_GetAttachedSurface(surface
, &caps
, &surface2
);
5711 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
5713 memset(&surface_desc
, 0, sizeof(surface_desc
));
5714 surface_desc
.dwSize
= sizeof(surface_desc
);
5715 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
5716 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
5717 memset(&surface_desc
, 0, sizeof(surface_desc
));
5718 surface_desc
.dwSize
= sizeof(surface_desc
);
5719 hr
= IDirectDrawSurface2_Lock(surface2
, NULL
, &surface_desc
, 0, NULL
);
5720 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
5721 IDirectDrawSurface2_Unlock(surface2
, NULL
);
5722 IDirectDrawSurface2_Unlock(surface
, NULL
);
5724 IDirectDrawSurface2_Release(surface2
);
5725 IDirectDrawSurface2_Release(surface
);
5726 refcount
= IDirectDraw2_Release(ddraw
);
5727 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5728 DestroyWindow(window
);
5731 static void test_palette_complex(void)
5733 IDirectDrawSurface
*surface1
;
5734 IDirectDrawSurface2
*surface
, *mipmap
, *tmp
;
5735 DDSURFACEDESC surface_desc
;
5736 IDirectDraw2
*ddraw
;
5737 IDirectDrawPalette
*palette
, *palette2
, *palette_mipmap
;
5741 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
5743 PALETTEENTRY palette_entries
[256];
5749 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5750 0, 0, 640, 480, 0, 0, 0, 0);
5751 ddraw
= create_ddraw();
5752 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5753 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5754 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5756 memset(&hal_caps
, 0, sizeof(hal_caps
));
5757 hal_caps
.dwSize
= sizeof(hal_caps
);
5758 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
5759 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
5760 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
5762 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
5763 IDirectDraw2_Release(ddraw
);
5764 DestroyWindow(window
);
5768 memset(&surface_desc
, 0, sizeof(surface_desc
));
5769 surface_desc
.dwSize
= sizeof(surface_desc
);
5770 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5771 surface_desc
.dwWidth
= 128;
5772 surface_desc
.dwHeight
= 128;
5773 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
5774 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5775 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
5776 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
5777 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5778 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5779 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
5780 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr
);
5781 IDirectDrawSurface_Release(surface1
);
5783 memset(palette_entries
, 0, sizeof(palette_entries
));
5784 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
5785 palette_entries
, &palette
, NULL
);
5786 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
5788 memset(palette_entries
, 0, sizeof(palette_entries
));
5789 palette_entries
[1].peRed
= 0xff;
5790 palette_entries
[1].peGreen
= 0x80;
5791 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
5792 palette_entries
, &palette_mipmap
, NULL
);
5793 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
5795 palette2
= (void *)0xdeadbeef;
5796 hr
= IDirectDrawSurface2_GetPalette(surface
, &palette2
);
5797 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
5798 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
5799 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
5800 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5801 hr
= IDirectDrawSurface2_GetPalette(surface
, &palette2
);
5802 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
5803 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
5804 IDirectDrawPalette_Release(palette2
);
5807 IDirectDrawSurface2_AddRef(mipmap
);
5808 for (i
= 0; i
< 7; ++i
)
5810 hr
= IDirectDrawSurface2_GetAttachedSurface(mipmap
, &caps
, &tmp
);
5811 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
5812 palette2
= (void *)0xdeadbeef;
5813 hr
= IDirectDrawSurface2_GetPalette(tmp
, &palette2
);
5814 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
5815 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
5817 hr
= IDirectDrawSurface2_SetPalette(tmp
, palette_mipmap
);
5818 ok(SUCCEEDED(hr
), "Failed to set palette, i %u, hr %#x.\n", i
, hr
);
5820 hr
= IDirectDrawSurface2_GetPalette(tmp
, &palette2
);
5821 ok(SUCCEEDED(hr
), "Failed to get palette, i %u, hr %#x.\n", i
, hr
);
5822 ok(palette_mipmap
== palette2
, "Got unexpected palette %p.\n", palette2
);
5823 IDirectDrawPalette_Release(palette2
);
5825 hr
= IDirectDrawSurface2_GetDC(tmp
, &dc
);
5826 ok(SUCCEEDED(hr
), "Failed to get DC, i %u, hr %#x.\n", i
, hr
);
5827 count
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
5828 ok(count
== 1, "Expected count 1, got %u.\n", count
);
5829 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x.\n", rgbquad
.rgbRed
);
5830 ok(rgbquad
.rgbGreen
== 0x80, "Expected rgbGreen = 0x80, got %#x.\n", rgbquad
.rgbGreen
);
5831 ok(rgbquad
.rgbBlue
== 0x0, "Expected rgbBlue = 0x0, got %#x.\n", rgbquad
.rgbBlue
);
5832 hr
= IDirectDrawSurface2_ReleaseDC(tmp
, dc
);
5833 ok(SUCCEEDED(hr
), "Failed to release DC, i %u, hr %#x.\n", i
, hr
);
5835 IDirectDrawSurface2_Release(mipmap
);
5839 hr
= IDirectDrawSurface2_GetAttachedSurface(mipmap
, &caps
, &tmp
);
5840 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
5841 IDirectDrawSurface2_Release(mipmap
);
5842 refcount
= IDirectDrawSurface2_Release(surface
);
5843 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5844 refcount
= IDirectDrawPalette_Release(palette_mipmap
);
5845 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5846 refcount
= IDirectDrawPalette_Release(palette
);
5847 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5849 refcount
= IDirectDraw2_Release(ddraw
);
5850 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5851 DestroyWindow(window
);
5854 static void test_p8_rgb_blit(void)
5856 IDirectDrawSurface
*src
, *dst
;
5857 DDSURFACEDESC surface_desc
;
5858 IDirectDraw2
*ddraw
;
5859 IDirectDrawPalette
*palette
;
5863 PALETTEENTRY palette_entries
[256];
5865 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
5866 static const D3DCOLOR expected
[] =
5868 0x00101010, 0x00010101, 0x00020202, 0x00030303,
5869 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
5873 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5874 0, 0, 640, 480, 0, 0, 0, 0);
5875 ddraw
= create_ddraw();
5876 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5877 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5878 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5880 memset(palette_entries
, 0, sizeof(palette_entries
));
5881 palette_entries
[1].peGreen
= 0xff;
5882 palette_entries
[2].peBlue
= 0xff;
5883 palette_entries
[3].peFlags
= 0xff;
5884 palette_entries
[4].peRed
= 0xff;
5885 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
5886 palette_entries
, &palette
, NULL
);
5887 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
5889 memset(&surface_desc
, 0, sizeof(surface_desc
));
5890 surface_desc
.dwSize
= sizeof(surface_desc
);
5891 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5892 surface_desc
.dwWidth
= 8;
5893 surface_desc
.dwHeight
= 1;
5894 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5895 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5896 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
5897 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
5898 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
5899 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5901 memset(&surface_desc
, 0, sizeof(surface_desc
));
5902 surface_desc
.dwSize
= sizeof(surface_desc
);
5903 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5904 surface_desc
.dwWidth
= 8;
5905 surface_desc
.dwHeight
= 1;
5906 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5907 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5908 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
5909 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5910 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5911 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5912 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5913 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
5914 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
5915 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5917 memset(&surface_desc
, 0, sizeof(surface_desc
));
5918 surface_desc
.dwSize
= sizeof(surface_desc
);
5919 hr
= IDirectDrawSurface_Lock(src
, NULL
, &surface_desc
, 0, NULL
);
5920 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
5921 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
5922 hr
= IDirectDrawSurface_Unlock(src
, NULL
);
5923 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
5925 hr
= IDirectDrawSurface_SetPalette(src
, palette
);
5926 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5927 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
5928 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
5929 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
5930 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
5931 "Failed to blit, hr %#x.\n", hr
);
5935 for (x
= 0; x
< sizeof(expected
) / sizeof(*expected
); x
++)
5937 color
= get_surface_color(dst
, x
, 0);
5938 todo_wine
ok(compare_color(color
, expected
[x
], 0),
5939 "Pixel %u: Got color %#x, expected %#x.\n",
5940 x
, color
, expected
[x
]);
5944 IDirectDrawSurface_Release(src
);
5945 IDirectDrawSurface_Release(dst
);
5946 IDirectDrawPalette_Release(palette
);
5948 refcount
= IDirectDraw2_Release(ddraw
);
5949 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5950 DestroyWindow(window
);
5953 static void test_material(void)
5955 D3DMATERIALHANDLE mat_handle
, tmp
;
5956 IDirect3DMaterial2
*material
;
5957 IDirect3DViewport2
*viewport
;
5958 IDirect3DDevice2
*device
;
5959 IDirectDrawSurface
*rt
;
5960 IDirectDraw2
*ddraw
;
5968 static D3DVERTEX quad
[] =
5970 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5971 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5972 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5973 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5978 D3DCOLOR expected_color
;
5983 {FALSE
, 0x00ffffff},
5985 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
5987 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5988 0, 0, 640, 480, 0, 0, 0, 0);
5989 ddraw
= create_ddraw();
5990 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5991 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
5993 skip("Failed to create a 3D device, skipping test.\n");
5994 DestroyWindow(window
);
5998 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
5999 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
6001 material
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
6002 viewport
= create_viewport(device
, 0, 0, 640, 480);
6003 viewport_set_background(device
, viewport
, material
);
6004 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
6005 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
6007 destroy_material(material
);
6008 material
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
6009 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
6010 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
6012 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
6013 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
6014 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
6015 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
6016 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
6017 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
6018 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
6019 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
6020 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, 0);
6021 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
6022 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
6023 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
6024 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
6026 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
6028 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
6029 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6031 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, test_data
[i
].material
? mat_handle
: 0);
6032 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
6034 hr
= IDirect3DDevice2_BeginScene(device
);
6035 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6036 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_VERTEX
, quad
, 4, 0);
6037 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6038 hr
= IDirect3DDevice2_EndScene(device
);
6039 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6040 color
= get_surface_color(rt
, 320, 240);
6041 ok(compare_color(color
, test_data
[i
].expected_color
, 1),
6042 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
6045 destroy_material(material
);
6046 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
6047 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
6048 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
6050 hr
= IDirect3DViewport2_SetBackground(viewport
, mat_handle
);
6051 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
6052 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
6053 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
6054 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
6055 ok(valid
, "Got unexpected valid %#x.\n", valid
);
6056 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6057 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6058 color
= get_surface_color(rt
, 320, 240);
6059 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
6061 hr
= IDirect3DViewport2_SetBackground(viewport
, 0);
6062 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
6063 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
6064 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
6065 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
6066 ok(valid
, "Got unexpected valid %#x.\n", valid
);
6067 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6068 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6069 color
= get_surface_color(rt
, 320, 240);
6070 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
6072 destroy_viewport(device
, viewport
);
6073 viewport
= create_viewport(device
, 0, 0, 640, 480);
6075 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
6076 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
6077 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
6078 ok(!valid
, "Got unexpected valid %#x.\n", valid
);
6079 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6080 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6081 color
= get_surface_color(rt
, 320, 240);
6082 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color
);
6084 destroy_viewport(device
, viewport
);
6085 destroy_material(material
);
6086 IDirectDrawSurface_Release(rt
);
6087 refcount
= IDirect3DDevice2_Release(device
);
6088 ok(!refcount
, "Device has %u references left.\n", refcount
);
6089 refcount
= IDirectDraw2_Release(ddraw
);
6090 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
6091 DestroyWindow(window
);
6094 static void test_palette_gdi(void)
6096 IDirectDrawSurface
*surface
, *primary
;
6097 DDSURFACEDESC surface_desc
;
6098 IDirectDraw2
*ddraw
;
6099 IDirectDrawPalette
*palette
, *palette2
;
6103 PALETTEENTRY palette_entries
[256];
6106 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
6107 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
6108 * not the point of this test. */
6109 static const RGBQUAD expected1
[] =
6111 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
6112 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
6114 static const RGBQUAD expected2
[] =
6116 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
6117 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
6119 static const RGBQUAD expected3
[] =
6121 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
6122 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
6124 HPALETTE ddraw_palette_handle
;
6125 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
6126 RGBQUAD rgbquad
[255];
6127 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
6129 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6130 0, 0, 640, 480, 0, 0, 0, 0);
6131 ddraw
= create_ddraw();
6132 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6133 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6134 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6136 memset(&surface_desc
, 0, sizeof(surface_desc
));
6137 surface_desc
.dwSize
= sizeof(surface_desc
);
6138 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6139 surface_desc
.dwWidth
= 16;
6140 surface_desc
.dwHeight
= 16;
6141 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6142 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6143 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
6144 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
6145 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6146 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6148 /* Avoid colors from the Windows default palette. */
6149 memset(palette_entries
, 0, sizeof(palette_entries
));
6150 palette_entries
[1].peRed
= 0x01;
6151 palette_entries
[2].peGreen
= 0x02;
6152 palette_entries
[3].peBlue
= 0x03;
6153 palette_entries
[4].peRed
= 0x13;
6154 palette_entries
[4].peGreen
= 0x14;
6155 palette_entries
[4].peBlue
= 0x15;
6156 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6157 palette_entries
, &palette
, NULL
);
6158 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6160 /* If there is no palette assigned and the display mode is not 8 bpp, some
6161 * drivers refuse to create a DC while others allow it. If a DC is created,
6162 * the DIB color table is uninitialized and contains random colors. No error
6163 * is generated when trying to read pixels and random garbage is returned.
6165 * The most likely explanation is that if the driver creates a DC, it (or
6166 * the higher-level runtime) uses GetSystemPaletteEntries to find the
6167 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
6168 * contains uninitialized garbage. See comments below for the P8 case. */
6170 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
6171 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6172 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
6173 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6174 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
6175 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
6176 "Got unexpected palette %p, expected %p.\n",
6177 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
6179 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
6180 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
6181 for (i
= 0; i
< sizeof(expected1
) / sizeof(*expected1
); i
++)
6183 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
6184 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6185 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
6186 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
6188 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
6190 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
6191 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
6192 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
6195 /* Update the palette while the DC is in use. This does not modify the DC. */
6196 palette_entries
[4].peRed
= 0x23;
6197 palette_entries
[4].peGreen
= 0x24;
6198 palette_entries
[4].peBlue
= 0x25;
6199 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
6200 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#x.\n", hr
);
6202 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
6203 ok(i
== 1, "Expected count 1, got %u.\n", i
);
6204 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
6205 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6206 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
6207 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
6209 /* Neither does re-setting the palette. */
6210 hr
= IDirectDrawSurface_SetPalette(surface
, NULL
);
6211 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6212 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
6213 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6215 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
6216 ok(i
== 1, "Expected count 1, got %u.\n", i
);
6217 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
6218 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6219 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
6220 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
6222 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
6223 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6225 /* Refresh the DC. This updates the palette. */
6226 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
6227 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6228 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
6229 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
6230 for (i
= 0; i
< sizeof(expected2
) / sizeof(*expected2
); i
++)
6232 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
6233 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6234 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
6235 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
6237 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
6239 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
6240 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
6241 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
6243 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
6244 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6246 refcount
= IDirectDrawSurface_Release(surface
);
6247 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6249 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
6251 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
6252 IDirectDrawPalette_Release(palette
);
6253 IDirectDraw2_Release(ddraw
);
6254 DestroyWindow(window
);
6257 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
6258 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
6259 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6261 memset(&surface_desc
, 0, sizeof(surface_desc
));
6262 surface_desc
.dwSize
= sizeof(surface_desc
);
6263 surface_desc
.dwFlags
= DDSD_CAPS
;
6264 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
6265 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
6266 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6268 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
6269 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6270 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
6271 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6272 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
6273 /* Windows 2000 on the testbot assigns a different palette to the primary. Refrast? */
6274 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
) || broken(TRUE
),
6275 "Got unexpected palette %p, expected %p.\n",
6276 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
6277 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
6279 /* The primary uses the system palette. In exclusive mode, the system palette matches
6280 * the ddraw palette attached to the primary, so the result is what you would expect
6281 * from a regular surface. Tests for the interaction between the ddraw palette and
6282 * the system palette are not included pending an application that depends on this.
6283 * The relation between those causes problems on Windows Vista and newer for games
6284 * like Age of Empires or Starcraft. Don't emulate it without a real need. */
6285 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
6286 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
6287 for (i
= 0; i
< sizeof(expected2
) / sizeof(*expected2
); i
++)
6289 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
6290 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6291 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
6292 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
6294 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
6296 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
6297 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
6298 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
6300 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
6301 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6303 memset(&surface_desc
, 0, sizeof(surface_desc
));
6304 surface_desc
.dwSize
= sizeof(surface_desc
);
6305 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6306 surface_desc
.dwWidth
= 16;
6307 surface_desc
.dwHeight
= 16;
6308 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6309 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6310 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6312 /* Here the offscreen surface appears to use the primary's palette,
6313 * but in all likelyhood it is actually the system palette. */
6314 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
6315 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6316 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
6317 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
6318 for (i
= 0; i
< sizeof(expected2
) / sizeof(*expected2
); i
++)
6320 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
6321 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6322 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
6323 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
6325 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
6327 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
6328 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
6329 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
6331 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
6332 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6334 /* On real hardware a change to the primary surface's palette applies immediately,
6335 * even on device contexts from offscreen surfaces that do not have their own
6336 * palette. On the testbot VMs this is not the case. Don't test this until we
6337 * know of an application that depends on this. */
6339 memset(palette_entries
, 0, sizeof(palette_entries
));
6340 palette_entries
[1].peBlue
= 0x40;
6341 palette_entries
[2].peRed
= 0x40;
6342 palette_entries
[3].peGreen
= 0x40;
6343 palette_entries
[4].peRed
= 0x12;
6344 palette_entries
[4].peGreen
= 0x34;
6345 palette_entries
[4].peBlue
= 0x56;
6346 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6347 palette_entries
, &palette2
, NULL
);
6348 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6349 hr
= IDirectDrawSurface_SetPalette(surface
, palette2
);
6350 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6352 /* A palette assigned to the offscreen surface overrides the primary / system
6354 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
6355 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6356 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
6357 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
6358 for (i
= 0; i
< sizeof(expected3
) / sizeof(*expected3
); i
++)
6360 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
6361 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6362 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
6363 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
6365 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
6367 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
6368 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
6369 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
6371 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
6372 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6374 refcount
= IDirectDrawSurface_Release(surface
);
6375 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6377 /* The Windows 8 testbot keeps extra references to the primary and
6378 * backbuffer while in 8 bpp mode. */
6379 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
6380 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
6382 refcount
= IDirectDrawSurface_Release(primary
);
6383 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6384 refcount
= IDirectDrawPalette_Release(palette2
);
6385 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6386 refcount
= IDirectDrawPalette_Release(palette
);
6387 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6388 refcount
= IDirectDraw2_Release(ddraw
);
6389 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6390 DestroyWindow(window
);
6393 static void test_palette_alpha(void)
6395 IDirectDrawSurface
*surface1
;
6396 IDirectDrawSurface2
*surface
;
6397 DDSURFACEDESC surface_desc
;
6398 IDirectDraw2
*ddraw
;
6399 IDirectDrawPalette
*palette
;
6403 PALETTEENTRY palette_entries
[256];
6408 BOOL attach_allowed
;
6413 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
6414 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
6415 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
6418 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6419 0, 0, 640, 480, 0, 0, 0, 0);
6420 ddraw
= create_ddraw();
6421 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6422 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
6424 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
6425 IDirectDraw2_Release(ddraw
);
6426 DestroyWindow(window
);
6429 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6430 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6432 memset(palette_entries
, 0, sizeof(palette_entries
));
6433 palette_entries
[1].peFlags
= 0x42;
6434 palette_entries
[2].peFlags
= 0xff;
6435 palette_entries
[3].peFlags
= 0x80;
6436 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
6437 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6439 memset(palette_entries
, 0x66, sizeof(palette_entries
));
6440 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
6441 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
6442 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
6443 palette_entries
[0].peFlags
);
6444 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
6445 palette_entries
[1].peFlags
);
6446 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
6447 palette_entries
[2].peFlags
);
6448 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
6449 palette_entries
[3].peFlags
);
6451 IDirectDrawPalette_Release(palette
);
6453 memset(palette_entries
, 0, sizeof(palette_entries
));
6454 palette_entries
[1].peFlags
= 0x42;
6455 palette_entries
[1].peRed
= 0xff;
6456 palette_entries
[2].peFlags
= 0xff;
6457 palette_entries
[3].peFlags
= 0x80;
6458 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
6459 palette_entries
, &palette
, NULL
);
6460 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6462 memset(palette_entries
, 0x66, sizeof(palette_entries
));
6463 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
6464 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
6465 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
6466 palette_entries
[0].peFlags
);
6467 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
6468 palette_entries
[1].peFlags
);
6469 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
6470 palette_entries
[2].peFlags
);
6471 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
6472 palette_entries
[3].peFlags
);
6474 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); i
++)
6476 memset(&surface_desc
, 0, sizeof(surface_desc
));
6477 surface_desc
.dwSize
= sizeof(surface_desc
);
6478 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
6479 surface_desc
.dwWidth
= 128;
6480 surface_desc
.dwHeight
= 128;
6481 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
6482 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6483 ok(SUCCEEDED(hr
), "Failed to create %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
6484 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
6485 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr
);
6486 IDirectDrawSurface_Release(surface1
);
6488 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
6489 if (test_data
[i
].attach_allowed
)
6490 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
6492 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
6500 hr
= IDirectDrawSurface2_GetDC(surface
, &dc
);
6501 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_CANTCREATEDC
) /* Win2k testbot */,
6502 "Failed to get DC, hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
6505 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
6506 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
6507 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
6508 rgbquad
.rgbRed
, test_data
[i
].name
);
6509 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
6510 rgbquad
.rgbGreen
, test_data
[i
].name
);
6511 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
6512 rgbquad
.rgbBlue
, test_data
[i
].name
);
6513 todo_wine
ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
6514 rgbquad
.rgbReserved
, test_data
[i
].name
);
6515 hr
= IDirectDrawSurface2_ReleaseDC(surface
, dc
);
6516 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6519 IDirectDrawSurface2_Release(surface
);
6522 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
6523 memset(&surface_desc
, 0, sizeof(surface_desc
));
6524 surface_desc
.dwSize
= sizeof(surface_desc
);
6525 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6526 surface_desc
.dwWidth
= 128;
6527 surface_desc
.dwHeight
= 128;
6528 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6529 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6530 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6531 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6532 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6533 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6534 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6535 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6536 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6537 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
6538 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr
);
6539 IDirectDrawSurface_Release(surface1
);
6541 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
6542 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
6543 IDirectDrawSurface2_Release(surface
);
6545 /* The Windows 8 testbot keeps extra references to the primary
6546 * while in 8 bpp mode. */
6547 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
6548 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
6550 refcount
= IDirectDrawPalette_Release(palette
);
6551 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6552 refcount
= IDirectDraw2_Release(ddraw
);
6553 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6554 DestroyWindow(window
);
6557 static void test_lost_device(void)
6559 IDirectDrawSurface
*surface
;
6560 DDSURFACEDESC surface_desc
;
6561 IDirectDraw2
*ddraw
;
6567 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6568 0, 0, 640, 480, 0, 0, 0, 0);
6569 ddraw
= create_ddraw();
6570 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6571 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6572 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6574 memset(&surface_desc
, 0, sizeof(surface_desc
));
6575 surface_desc
.dwSize
= sizeof(surface_desc
);
6576 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
6577 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
6578 surface_desc
.dwBackBufferCount
= 1;
6579 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6580 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6582 hr
= IDirectDrawSurface_IsLost(surface
);
6583 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6584 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6585 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6587 ret
= SetForegroundWindow(GetDesktopWindow());
6588 ok(ret
, "Failed to set foreground window.\n");
6589 hr
= IDirectDrawSurface_IsLost(surface
);
6590 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6591 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6592 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6594 ret
= SetForegroundWindow(window
);
6595 ok(ret
, "Failed to set foreground window.\n");
6596 hr
= IDirectDrawSurface_IsLost(surface
);
6597 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6598 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6599 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6601 hr
= restore_surfaces(ddraw
);
6602 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6603 hr
= IDirectDrawSurface_IsLost(surface
);
6604 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6605 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6606 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6608 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6609 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6610 hr
= IDirectDrawSurface_IsLost(surface
);
6611 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6612 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6613 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6615 /* Trying to restore the primary will crash, probably because flippable
6616 * surfaces can't exist in DDSCL_NORMAL. */
6617 IDirectDrawSurface_Release(surface
);
6618 memset(&surface_desc
, 0, sizeof(surface_desc
));
6619 surface_desc
.dwSize
= sizeof(surface_desc
);
6620 surface_desc
.dwFlags
= DDSD_CAPS
;
6621 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
6622 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6623 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6625 hr
= IDirectDrawSurface_IsLost(surface
);
6626 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6628 ret
= SetForegroundWindow(GetDesktopWindow());
6629 ok(ret
, "Failed to set foreground window.\n");
6630 hr
= IDirectDrawSurface_IsLost(surface
);
6631 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6633 ret
= SetForegroundWindow(window
);
6634 ok(ret
, "Failed to set foreground window.\n");
6635 hr
= IDirectDrawSurface_IsLost(surface
);
6636 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6638 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6639 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6640 hr
= IDirectDrawSurface_IsLost(surface
);
6641 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6643 hr
= restore_surfaces(ddraw
);
6644 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6645 hr
= IDirectDrawSurface_IsLost(surface
);
6646 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6648 IDirectDrawSurface_Release(surface
);
6649 refcount
= IDirectDraw2_Release(ddraw
);
6650 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6651 DestroyWindow(window
);
6656 IDirectDraw2
*ddraw
;
6658 if (!(ddraw
= create_ddraw()))
6660 skip("Failed to create a ddraw object, skipping tests.\n");
6663 IDirectDraw2_Release(ddraw
);
6665 test_coop_level_create_device_window();
6667 test_coop_level_d3d_state();
6668 test_surface_interface_mismatch();
6669 test_coop_level_threaded();
6671 test_texture_load_ckey();
6680 test_window_style();
6681 test_redundant_mode_set();
6682 test_coop_level_mode_set();
6683 test_coop_level_mode_set_multi();
6685 test_coop_level_surf_create();
6686 test_coop_level_multi_window();
6687 test_clear_rect_count();
6688 test_coop_level_versions();
6689 test_lighting_interface_versions();
6690 test_coop_level_activateapp();
6691 test_unsupported_formats();
6693 test_primary_caps();
6694 test_surface_lock();
6695 test_surface_discard();
6697 test_set_surface_desc();
6698 test_user_memory_getdc();
6699 test_sysmem_overlay();
6700 test_primary_palette();
6701 test_surface_attachment();
6702 test_pixel_format();
6703 test_create_surface_pitch();
6705 test_palette_complex();
6709 test_palette_alpha();