2 * Copyright 2005 Antoine Chavasse (a.chavasse@gmail.com)
3 * Copyright 2008, 2011, 2012-2014 Stefan Dösinger for CodeWeavers
4 * Copyright 2011-2014 Henri Verbeet for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/test.h"
28 static BOOL is_ddraw64
= sizeof(DWORD
) != sizeof(DWORD
*);
29 static DEVMODEW registry_mode
;
31 static HRESULT (WINAPI
*pDwmIsCompositionEnabled
)(BOOL
*);
34 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
42 struct create_window_thread_param
45 HANDLE window_created
;
46 HANDLE destroy_window
;
50 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
52 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
54 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
56 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
58 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
62 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
72 if (abs(x
- y
) > ulps
)
78 static BOOL
compare_vec4(const struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
80 return compare_float(vec
->x
, x
, ulps
)
81 && compare_float(vec
->y
, y
, ulps
)
82 && compare_float(vec
->z
, z
, ulps
)
83 && compare_float(vec
->w
, w
, ulps
);
86 static IDirectDrawSurface
*create_overlay(IDirectDraw2
*ddraw
,
87 unsigned int width
, unsigned int height
, DWORD format
)
89 IDirectDrawSurface
*surface
;
92 memset(&desc
, 0, sizeof(desc
));
93 desc
.dwSize
= sizeof(desc
);
94 desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
96 desc
.dwHeight
= height
;
97 desc
.ddsCaps
.dwCaps
= DDSCAPS_OVERLAY
;
98 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
99 desc
.ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
100 desc
.ddpfPixelFormat
.dwFourCC
= format
;
102 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &desc
, &surface
, NULL
)))
107 static DWORD WINAPI
create_window_thread_proc(void *param
)
109 struct create_window_thread_param
*p
= param
;
113 p
->window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
114 0, 0, 640, 480, 0, 0, 0, 0);
115 ret
= SetEvent(p
->window_created
);
116 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
122 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
123 DispatchMessageA(&msg
);
124 res
= WaitForSingleObject(p
->destroy_window
, 100);
125 if (res
== WAIT_OBJECT_0
)
127 if (res
!= WAIT_TIMEOUT
)
129 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
134 DestroyWindow(p
->window
);
139 static void create_window_thread(struct create_window_thread_param
*p
)
143 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
144 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
145 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
146 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
147 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
148 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
149 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
150 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
153 static void destroy_window_thread(struct create_window_thread_param
*p
)
155 SetEvent(p
->destroy_window
);
156 WaitForSingleObject(p
->thread
, INFINITE
);
157 CloseHandle(p
->destroy_window
);
158 CloseHandle(p
->window_created
);
159 CloseHandle(p
->thread
);
162 static IDirectDrawSurface
*get_depth_stencil(IDirect3DDevice2
*device
)
164 IDirectDrawSurface
*rt
, *ret
;
165 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
168 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
169 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
170 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ret
);
171 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
172 IDirectDrawSurface_Release(rt
);
176 static HRESULT
set_display_mode(IDirectDraw2
*ddraw
, DWORD width
, DWORD height
)
178 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
180 return IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0);
183 static D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
185 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
186 DDSURFACEDESC surface_desc
;
190 memset(&surface_desc
, 0, sizeof(surface_desc
));
191 surface_desc
.dwSize
= sizeof(surface_desc
);
193 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
194 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
198 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
200 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
201 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
206 static DWORD
get_device_z_depth(IDirect3DDevice2
*device
)
208 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
209 IDirectDrawSurface
*ds
, *rt
;
213 if (FAILED(IDirect3DDevice2_GetRenderTarget(device
, &rt
)))
216 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ds
);
217 IDirectDrawSurface_Release(rt
);
221 desc
.dwSize
= sizeof(desc
);
222 hr
= IDirectDrawSurface_GetSurfaceDesc(ds
, &desc
);
223 IDirectDrawSurface_Release(ds
);
227 return U2(desc
).dwZBufferBitDepth
;
230 static IDirectDraw2
*create_ddraw(void)
232 IDirectDraw2
*ddraw2
;
236 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
239 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw2
);
240 IDirectDraw_Release(ddraw1
);
247 static IDirect3DDevice2
*create_device(IDirectDraw2
*ddraw
, HWND window
, DWORD coop_level
)
249 static const DWORD z_depths
[] = {32, 24, 16};
250 IDirectDrawSurface
*surface
, *ds
;
251 IDirect3DDevice2
*device
= NULL
;
252 DDSURFACEDESC surface_desc
;
257 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, coop_level
);
258 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
260 memset(&surface_desc
, 0, sizeof(surface_desc
));
261 surface_desc
.dwSize
= sizeof(surface_desc
);
262 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
263 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
264 surface_desc
.dwWidth
= 640;
265 surface_desc
.dwHeight
= 480;
267 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
268 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
270 if (coop_level
& DDSCL_NORMAL
)
272 IDirectDrawClipper
*clipper
;
274 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
275 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
276 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
277 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
278 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
279 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
280 IDirectDrawClipper_Release(clipper
);
283 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
286 IDirectDrawSurface_Release(surface
);
290 /* We used to use EnumDevices() for this, but it seems
291 * D3DDEVICEDESC.dwDeviceZBufferBitDepth only has a very casual
292 * relationship with reality. */
293 for (i
= 0; i
< sizeof(z_depths
) / sizeof(*z_depths
); ++i
)
295 memset(&surface_desc
, 0, sizeof(surface_desc
));
296 surface_desc
.dwSize
= sizeof(surface_desc
);
297 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
298 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
299 U2(surface_desc
).dwZBufferBitDepth
= z_depths
[i
];
300 surface_desc
.dwWidth
= 640;
301 surface_desc
.dwHeight
= 480;
302 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
)))
305 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
306 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
307 IDirectDrawSurface_Release(ds
);
311 if (SUCCEEDED(IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
)))
314 IDirectDrawSurface_DeleteAttachedSurface(surface
, 0, ds
);
317 IDirect3D2_Release(d3d
);
318 IDirectDrawSurface_Release(surface
);
322 static IDirect3DViewport2
*create_viewport(IDirect3DDevice2
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
324 IDirect3DViewport2
*viewport
;
329 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
330 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
331 hr
= IDirect3D2_CreateViewport(d3d
, &viewport
, NULL
);
332 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
333 hr
= IDirect3DDevice2_AddViewport(device
, viewport
);
334 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
335 memset(&vp
, 0, sizeof(vp
));
336 vp
.dwSize
= sizeof(vp
);
343 vp
.dvClipWidth
= 2.0f
;
344 vp
.dvClipHeight
= 2.0f
;
347 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp
);
348 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
349 IDirect3D2_Release(d3d
);
354 static void viewport_set_background(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
,
355 IDirect3DMaterial2
*material
)
357 D3DMATERIALHANDLE material_handle
;
360 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &material_handle
);
361 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
362 hr
= IDirect3DViewport2_SetBackground(viewport
, material_handle
);
363 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
366 static void destroy_viewport(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
)
370 hr
= IDirect3DDevice2_DeleteViewport(device
, viewport
);
371 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
372 IDirect3DViewport2_Release(viewport
);
375 static IDirect3DMaterial2
*create_material(IDirect3DDevice2
*device
, D3DMATERIAL
*mat
)
377 IDirect3DMaterial2
*material
;
381 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
382 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
383 hr
= IDirect3D2_CreateMaterial(d3d
, &material
, NULL
);
384 ok(SUCCEEDED(hr
), "Failed to create material, hr %#x.\n", hr
);
385 hr
= IDirect3DMaterial2_SetMaterial(material
, mat
);
386 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
387 IDirect3D2_Release(d3d
);
392 static IDirect3DMaterial2
*create_diffuse_material(IDirect3DDevice2
*device
, float r
, float g
, float b
, float a
)
396 memset(&mat
, 0, sizeof(mat
));
397 mat
.dwSize
= sizeof(mat
);
398 U1(U(mat
).diffuse
).r
= r
;
399 U2(U(mat
).diffuse
).g
= g
;
400 U3(U(mat
).diffuse
).b
= b
;
401 U4(U(mat
).diffuse
).a
= a
;
403 return create_material(device
, &mat
);
406 static IDirect3DMaterial2
*create_specular_material(IDirect3DDevice2
*device
,
407 float r
, float g
, float b
, float a
, float power
)
411 memset(&mat
, 0, sizeof(mat
));
412 mat
.dwSize
= sizeof(mat
);
413 U1(U2(mat
).specular
).r
= r
;
414 U2(U2(mat
).specular
).g
= g
;
415 U3(U2(mat
).specular
).b
= b
;
416 U4(U2(mat
).specular
).a
= a
;
417 U4(mat
).power
= power
;
419 return create_material(device
, &mat
);
422 static IDirect3DMaterial2
*create_emissive_material(IDirect3DDevice2
*device
, float r
, float g
, float b
, float a
)
426 memset(&mat
, 0, sizeof(mat
));
427 mat
.dwSize
= sizeof(mat
);
428 U1(U3(mat
).emissive
).r
= r
;
429 U2(U3(mat
).emissive
).g
= g
;
430 U3(U3(mat
).emissive
).b
= b
;
431 U4(U3(mat
).emissive
).a
= a
;
433 return create_material(device
, &mat
);
436 static void destroy_material(IDirect3DMaterial2
*material
)
438 IDirect3DMaterial2_Release(material
);
445 WPARAM expect_wparam
;
448 static const struct message
*expect_messages
;
450 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
452 if (expect_messages
&& message
== expect_messages
->message
)
454 if (expect_messages
->check_wparam
)
455 ok (wparam
== expect_messages
->expect_wparam
,
456 "Got unexpected wparam %lx for message %x, expected %lx.\n",
457 wparam
, message
, expect_messages
->expect_wparam
);
462 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
465 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
466 * interface. This prevents subsequent SetCooperativeLevel() calls on a
467 * different window from failing with DDERR_HWNDALREADYSET. */
468 static void fix_wndproc(HWND window
, LONG_PTR proc
)
473 if (!(ddraw
= create_ddraw()))
476 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
477 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
478 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
479 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
480 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
482 IDirectDraw2_Release(ddraw
);
485 static HRESULT CALLBACK
restore_callback(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
487 HRESULT hr
= IDirectDrawSurface_Restore(surface
);
488 ok(SUCCEEDED(hr
) || hr
== DDERR_IMPLICITLYCREATED
, "Failed to restore surface, hr %#x.\n", hr
);
489 IDirectDrawSurface_Release(surface
);
494 static HRESULT
restore_surfaces(IDirectDraw2
*ddraw
)
496 return IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
,
497 NULL
, NULL
, restore_callback
);
500 static void test_coop_level_create_device_window(void)
502 HWND focus_window
, device_window
;
506 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
507 0, 0, 640, 480, 0, 0, 0, 0);
508 ddraw
= create_ddraw();
509 ok(!!ddraw
, "Failed to create a ddraw object.\n");
511 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
512 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
513 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
514 ok(!device_window
, "Unexpected device window found.\n");
515 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
516 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
517 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
518 ok(!device_window
, "Unexpected device window found.\n");
519 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
520 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
521 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
522 ok(!device_window
, "Unexpected device window found.\n");
523 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
524 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
525 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
526 ok(!device_window
, "Unexpected device window found.\n");
527 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
528 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
529 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
530 ok(!device_window
, "Unexpected device window found.\n");
532 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
533 if (broken(hr
== DDERR_INVALIDPARAMS
))
535 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
536 IDirectDraw2_Release(ddraw
);
537 DestroyWindow(focus_window
);
541 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
542 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
543 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
544 ok(!device_window
, "Unexpected device window found.\n");
545 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
546 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
547 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
548 ok(!device_window
, "Unexpected device window found.\n");
550 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
551 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
552 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
553 ok(!device_window
, "Unexpected device window found.\n");
554 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
555 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
556 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
557 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
558 ok(!!device_window
, "Device window not found.\n");
560 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
561 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
562 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
563 ok(!device_window
, "Unexpected device window found.\n");
564 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
565 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
566 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
567 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
568 ok(!!device_window
, "Device window not found.\n");
570 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
571 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
572 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
573 ok(!device_window
, "Unexpected device window found.\n");
574 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
575 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
576 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
577 ok(!device_window
, "Unexpected device window found.\n");
578 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
579 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
580 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
581 ok(!device_window
, "Unexpected device window found.\n");
582 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
583 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
584 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
585 ok(!!device_window
, "Device window not found.\n");
587 IDirectDraw2_Release(ddraw
);
588 DestroyWindow(focus_window
);
591 static void test_clipper_blt(void)
593 IDirectDrawSurface
*src_surface
, *dst_surface
;
594 RECT client_rect
, src_rect
;
595 IDirectDrawClipper
*clipper
;
596 DDSURFACEDESC surface_desc
;
597 unsigned int i
, j
, x
, y
;
609 static const DWORD src_data
[] =
611 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
612 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
613 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
615 static const D3DCOLOR expected1
[] =
617 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
618 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
619 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
620 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
622 /* Nvidia on Windows seems to have an off-by-one error
623 * when processing source rectangles. Our left = 1 and
624 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
625 * read as well, but only for the edge pixels on the
626 * output image. The bug happens on the y axis as well,
627 * but we only read one row there, and all source rows
628 * contain the same data. This bug is not dependent on
629 * the presence of a clipper. */
630 static const D3DCOLOR expected1_broken
[] =
632 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
633 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
634 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
635 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
637 static const D3DCOLOR expected2
[] =
639 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
640 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
641 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
642 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
645 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
646 10, 10, 640, 480, 0, 0, 0, 0);
647 ShowWindow(window
, SW_SHOW
);
648 ddraw
= create_ddraw();
649 ok(!!ddraw
, "Failed to create a ddraw object.\n");
651 ret
= GetClientRect(window
, &client_rect
);
652 ok(ret
, "Failed to get client rect.\n");
653 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
654 ok(ret
, "Failed to map client rect.\n");
656 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
657 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
659 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
660 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
661 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
662 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
663 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
664 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
665 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
666 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
667 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
668 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
669 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
670 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
671 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
672 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
673 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
674 "Got unexpected bounding rect %s, expected %s.\n",
675 wine_dbgstr_rect(&rgn_data
->rdh
.rcBound
), wine_dbgstr_rect(&client_rect
));
676 HeapFree(GetProcessHeap(), 0, rgn_data
);
678 r1
= CreateRectRgn(0, 0, 320, 240);
679 ok(!!r1
, "Failed to create region.\n");
680 r2
= CreateRectRgn(320, 240, 640, 480);
681 ok(!!r2
, "Failed to create region.\n");
682 CombineRgn(r1
, r1
, r2
, RGN_OR
);
683 ret
= GetRegionData(r1
, 0, NULL
);
684 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
685 ret
= GetRegionData(r1
, ret
, rgn_data
);
686 ok(!!ret
, "Failed to get region data.\n");
691 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
692 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
693 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
694 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
695 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
696 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
698 HeapFree(GetProcessHeap(), 0, rgn_data
);
700 memset(&surface_desc
, 0, sizeof(surface_desc
));
701 surface_desc
.dwSize
= sizeof(surface_desc
);
702 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
703 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
704 surface_desc
.dwWidth
= 640;
705 surface_desc
.dwHeight
= 480;
706 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
707 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
708 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
709 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
710 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
711 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
713 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
714 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
715 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
716 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
718 memset(&fx
, 0, sizeof(fx
));
719 fx
.dwSize
= sizeof(fx
);
720 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
721 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
722 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
723 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
725 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
726 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
727 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
728 ptr
= surface_desc
.lpSurface
;
729 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
730 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
731 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
732 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
733 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
735 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
736 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
738 SetRect(&src_rect
, 1, 1, 5, 2);
739 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
740 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
741 for (i
= 0; i
< 4; ++i
)
743 for (j
= 0; j
< 4; ++j
)
745 x
= 80 * ((2 * j
) + 1);
746 y
= 60 * ((2 * i
) + 1);
747 color
= get_surface_color(dst_surface
, x
, y
);
748 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
749 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
750 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
754 U5(fx
).dwFillColor
= 0xff0000ff;
755 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
756 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
757 for (i
= 0; i
< 4; ++i
)
759 for (j
= 0; j
< 4; ++j
)
761 x
= 80 * ((2 * j
) + 1);
762 y
= 60 * ((2 * i
) + 1);
763 color
= get_surface_color(dst_surface
, x
, y
);
764 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
765 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
769 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
770 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#x.\n", hr
);
772 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
773 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
774 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
775 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
776 DestroyWindow(window
);
777 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
778 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
779 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
780 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
781 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
782 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
783 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
784 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
785 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
786 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
787 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
788 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
790 IDirectDrawSurface_Release(dst_surface
);
791 IDirectDrawSurface_Release(src_surface
);
792 refcount
= IDirectDrawClipper_Release(clipper
);
793 ok(!refcount
, "Clipper has %u references left.\n", refcount
);
794 IDirectDraw2_Release(ddraw
);
797 static void test_coop_level_d3d_state(void)
799 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
800 IDirectDrawSurface
*rt
, *surface
;
801 IDirect3DMaterial2
*background
;
802 IDirect3DViewport2
*viewport
;
803 IDirect3DDevice2
*device
;
804 D3DMATERIAL material
;
811 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
812 0, 0, 640, 480, 0, 0, 0, 0);
813 ddraw
= create_ddraw();
814 ok(!!ddraw
, "Failed to create a ddraw object.\n");
815 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
817 skip("Failed to create a 3D device, skipping test.\n");
818 IDirectDraw2_Release(ddraw
);
819 DestroyWindow(window
);
823 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
824 viewport
= create_viewport(device
, 0, 0, 640, 480);
825 viewport_set_background(device
, viewport
, background
);
827 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
828 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
829 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
830 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
831 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
832 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
833 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
834 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
835 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
836 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
837 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
838 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
839 color
= get_surface_color(rt
, 320, 240);
840 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
842 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
843 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
844 hr
= IDirectDrawSurface_IsLost(rt
);
845 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
846 hr
= restore_surfaces(ddraw
);
847 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
849 memset(&material
, 0, sizeof(material
));
850 material
.dwSize
= sizeof(material
);
851 U1(U(material
).diffuse
).r
= 0.0f
;
852 U2(U(material
).diffuse
).g
= 1.0f
;
853 U3(U(material
).diffuse
).b
= 0.0f
;
854 U4(U(material
).diffuse
).a
= 1.0f
;
855 hr
= IDirect3DMaterial2_SetMaterial(background
, &material
);
856 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
858 hr
= IDirect3DDevice2_GetRenderTarget(device
, &surface
);
859 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
860 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
861 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
862 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
863 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
864 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
865 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
866 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
867 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
868 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
869 color
= get_surface_color(rt
, 320, 240);
870 ok(compare_color(color
, 0x0000ff00, 1) || broken(compare_color(color
, 0x00000000, 1)),
871 "Got unexpected color 0x%08x.\n", color
);
873 destroy_viewport(device
, viewport
);
874 destroy_material(background
);
875 IDirectDrawSurface_Release(surface
);
876 IDirectDrawSurface_Release(rt
);
877 IDirect3DDevice2_Release(device
);
878 IDirectDraw2_Release(ddraw
);
879 DestroyWindow(window
);
882 static void test_surface_interface_mismatch(void)
884 IDirectDraw2
*ddraw
= NULL
;
885 IDirect3D2
*d3d
= NULL
;
886 IDirectDrawSurface
*surface
= NULL
, *ds
;
887 IDirectDrawSurface3
*surface3
= NULL
;
888 IDirect3DDevice2
*device
= NULL
;
889 IDirect3DViewport2
*viewport
= NULL
;
890 IDirect3DMaterial2
*background
= NULL
;
891 DDSURFACEDESC surface_desc
;
897 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
899 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
900 0, 0, 640, 480, 0, 0, 0, 0);
901 ddraw
= create_ddraw();
902 ok(!!ddraw
, "Failed to create a ddraw object.\n");
903 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
905 skip("Failed to create a 3D device, skipping test.\n");
906 IDirectDraw2_Release(ddraw
);
907 DestroyWindow(window
);
910 z_depth
= get_device_z_depth(device
);
911 ok(!!z_depth
, "Failed to get device z depth.\n");
912 IDirect3DDevice2_Release(device
);
915 memset(&surface_desc
, 0, sizeof(surface_desc
));
916 surface_desc
.dwSize
= sizeof(surface_desc
);
917 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
918 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
919 surface_desc
.dwWidth
= 640;
920 surface_desc
.dwHeight
= 480;
922 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
923 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
925 hr
= IDirectDrawSurface2_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
928 skip("Failed to get the IDirectDrawSurface3 interface, skipping test.\n");
932 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
934 skip("D3D interface is not available, skipping test.\n");
938 memset(&surface_desc
, 0, sizeof(surface_desc
));
939 surface_desc
.dwSize
= sizeof(surface_desc
);
940 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
941 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
942 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
943 surface_desc
.dwWidth
= 640;
944 surface_desc
.dwHeight
= 480;
945 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
946 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
950 /* Using a different surface interface version still works */
951 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
952 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
953 refcount
= IDirectDrawSurface_Release(ds
);
954 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
959 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface
*)surface3
, &device
);
960 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
964 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
965 viewport
= create_viewport(device
, 0, 0, 640, 480);
966 viewport_set_background(device
, viewport
, background
);
968 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
969 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
970 color
= get_surface_color(surface
, 320, 240);
971 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
975 destroy_viewport(device
, viewport
);
977 destroy_material(background
);
978 if (surface3
) IDirectDrawSurface3_Release(surface3
);
979 if (surface
) IDirectDrawSurface_Release(surface
);
980 if (device
) IDirect3DDevice2_Release(device
);
981 if (d3d
) IDirect3D2_Release(d3d
);
982 if (ddraw
) IDirectDraw2_Release(ddraw
);
983 DestroyWindow(window
);
986 static void test_coop_level_threaded(void)
988 struct create_window_thread_param p
;
992 ddraw
= create_ddraw();
993 ok(!!ddraw
, "Failed to create a ddraw object.\n");
994 create_window_thread(&p
);
996 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
997 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
999 IDirectDraw2_Release(ddraw
);
1000 destroy_window_thread(&p
);
1003 static void test_depth_blit(void)
1005 static D3DLVERTEX quad1
[] =
1007 {{-1.0}, { 1.0}, {0.50f
}, 0, {0xff00ff00}},
1008 {{ 1.0}, { 1.0}, {0.50f
}, 0, {0xff00ff00}},
1009 {{-1.0}, {-1.0}, {0.50f
}, 0, {0xff00ff00}},
1010 {{ 1.0}, {-1.0}, {0.50f
}, 0, {0xff00ff00}},
1012 static const D3DCOLOR expected_colors
[4][4] =
1014 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1015 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1016 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1017 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1019 DDSURFACEDESC ddsd_new
, ddsd_existing
;
1021 IDirect3DDevice2
*device
;
1022 IDirectDrawSurface
*ds1
, *ds2
, *ds3
, *rt
;
1023 IDirect3DViewport2
*viewport
;
1024 RECT src_rect
, dst_rect
;
1028 IDirectDraw2
*ddraw
;
1032 IDirect3DMaterial2
*background
;
1034 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1035 0, 0, 640, 480, 0, 0, 0, 0);
1036 ddraw
= create_ddraw();
1037 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1038 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1040 skip("Failed to create a 3D device, skipping test.\n");
1041 IDirectDraw2_Release(ddraw
);
1042 DestroyWindow(window
);
1046 ds1
= get_depth_stencil(device
);
1048 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1049 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1050 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1051 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1052 hr
= IDirectDrawSurface_GetSurfaceDesc(ds1
, &ddsd_existing
);
1053 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
1054 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1055 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1056 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1057 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1058 ddsd_new
.ddpfPixelFormat
= ddsd_existing
.ddpfPixelFormat
;
1059 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1060 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1061 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1062 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1064 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1065 viewport
= create_viewport(device
, 0, 0, ddsd_existing
.dwWidth
, ddsd_existing
.dwHeight
);
1066 viewport_set_background(device
, viewport
, background
);
1067 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1068 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
1070 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1071 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
1072 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1073 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
1075 U1(d3drect
).x1
= U2(d3drect
).y1
= 0;
1076 U3(d3drect
).x2
= ddsd_existing
.dwWidth
; U4(d3drect
).y2
= ddsd_existing
.dwHeight
;
1077 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
);
1078 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
1081 SetRect(&src_rect
, 0, 0, 320, 240);
1082 SetRect(&dst_rect
, 0, 0, 320, 240);
1083 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1084 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1085 /* Different locations. */
1086 SetRect(&src_rect
, 0, 0, 320, 240);
1087 SetRect(&dst_rect
, 320, 240, 640, 480);
1088 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1089 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1091 SetRect(&src_rect
, 0, 0, 320, 240);
1092 SetRect(&dst_rect
, 0, 0, 640, 480);
1093 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1094 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1096 SetRect(&src_rect
, 0, 480, 640, 0);
1097 SetRect(&dst_rect
, 0, 0, 640, 480);
1098 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1099 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1100 SetRect(&src_rect
, 0, 0, 640, 480);
1101 SetRect(&dst_rect
, 0, 480, 640, 0);
1102 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1103 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1104 /* Full, explicit. */
1105 SetRect(&src_rect
, 0, 0, 640, 480);
1106 SetRect(&dst_rect
, 0, 0, 640, 480);
1107 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1108 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1109 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1111 /* Depth blit inside a BeginScene / EndScene pair */
1112 hr
= IDirect3DDevice2_BeginScene(device
);
1113 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1114 /* From the current depth stencil */
1115 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1116 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1117 /* To the current depth stencil */
1118 hr
= IDirectDrawSurface_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1119 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1120 /* Between unbound surfaces */
1121 hr
= IDirectDrawSurface_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1122 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1123 hr
= IDirect3DDevice2_EndScene(device
);
1124 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1126 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1127 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1128 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1129 * a reliable result(z = 0.0) */
1130 memset(&fx
, 0, sizeof(fx
));
1131 fx
.dwSize
= sizeof(fx
);
1132 U5(fx
).dwFillDepth
= 0;
1133 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1134 ok(SUCCEEDED(hr
), "Failed to clear the source z buffer, hr %#x.\n", hr
);
1136 /* This clears the Z buffer with 1.0 */
1137 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
);
1138 ok(SUCCEEDED(hr
), "Failed to clear the color and z buffers, hr %#x.\n", hr
);
1140 SetRect(&dst_rect
, 0, 0, 320, 240);
1141 hr
= IDirectDrawSurface_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1142 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1143 IDirectDrawSurface_Release(ds3
);
1144 IDirectDrawSurface_Release(ds2
);
1145 IDirectDrawSurface_Release(ds1
);
1147 hr
= IDirect3DDevice2_BeginScene(device
);
1148 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1149 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad1
, 4, 0);
1150 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1151 hr
= IDirect3DDevice2_EndScene(device
);
1152 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1154 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1155 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1156 for (i
= 0; i
< 4; ++i
)
1158 for (j
= 0; j
< 4; ++j
)
1160 unsigned int x
= 80 * ((2 * j
) + 1);
1161 unsigned int y
= 60 * ((2 * i
) + 1);
1162 color
= get_surface_color(rt
, x
, y
);
1163 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1164 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1167 IDirectDrawSurface_Release(rt
);
1169 destroy_viewport(device
, viewport
);
1170 destroy_material(background
);
1171 IDirect3DDevice2_Release(device
);
1172 IDirectDraw2_Release(ddraw
);
1173 DestroyWindow(window
);
1176 static void test_texture_load_ckey(void)
1178 IDirectDraw2
*ddraw
= NULL
;
1179 IDirectDrawSurface
*src
= NULL
;
1180 IDirectDrawSurface
*dst
= NULL
;
1181 IDirect3DTexture
*src_tex
= NULL
;
1182 IDirect3DTexture
*dst_tex
= NULL
;
1187 ddraw
= create_ddraw();
1188 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1189 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1190 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1192 memset(&ddsd
, 0, sizeof(ddsd
));
1193 ddsd
.dwSize
= sizeof(ddsd
);
1194 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1195 ddsd
.dwHeight
= 128;
1197 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1198 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1199 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1200 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1201 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1202 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1204 hr
= IDirectDrawSurface_QueryInterface(src
, &IID_IDirect3DTexture
, (void **)&src_tex
);
1205 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get Direct3DTexture interface, hr %#x.\n", hr
);
1208 /* 64 bit ddraw does not support d3d */
1209 skip("Could not get Direct3DTexture interface, skipping texture::Load color keying tests.\n");
1212 hr
= IDirectDrawSurface_QueryInterface(dst
, &IID_IDirect3DTexture
, (void **)&dst_tex
);
1213 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture interface, hr %#x.\n", hr
);
1215 /* No surface has a color key */
1216 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1217 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDCAPS
), "Got unexpected hr %#x.\n", hr
);
1220 /* Testbot Windows NT VMs */
1221 skip("IDirect3DTexture::Load does not work, skipping color keying tests.\n");
1225 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1226 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1227 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1228 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1229 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1231 /* Source surface has a color key */
1232 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1233 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1234 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1235 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1236 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1237 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1238 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1239 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1240 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1242 /* Both surfaces have a color key: Dest ckey is overwritten */
1243 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1244 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1245 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1246 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1247 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1248 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1249 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1250 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1251 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1253 /* Only the destination has a color key: It is not deleted */
1254 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1255 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1256 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1257 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1258 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1259 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1260 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1261 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1262 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1263 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1266 if (dst_tex
) IDirect3DTexture_Release(dst_tex
);
1267 if (src_tex
) IDirect3DTexture_Release(src_tex
);
1268 if (dst
) IDirectDrawSurface_Release(dst
);
1269 if (src
) IDirectDrawSurface_Release(src
);
1270 if (ddraw
) IDirectDraw2_Release(ddraw
);
1273 static ULONG
get_refcount(IUnknown
*test_iface
)
1275 IUnknown_AddRef(test_iface
);
1276 return IUnknown_Release(test_iface
);
1279 static void test_viewport(void)
1281 IDirectDraw2
*ddraw
;
1284 ULONG ref
, old_d3d_ref
;
1285 IDirect3DViewport
*viewport
;
1286 IDirect3DViewport2
*viewport2
, *another_vp
, *test_vp
;
1287 IDirect3DViewport3
*viewport3
;
1288 IDirectDrawGammaControl
*gamma
;
1290 IDirect3DDevice2
*device
;
1293 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1294 0, 0, 640, 480, 0, 0, 0, 0);
1295 ddraw
= create_ddraw();
1296 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1297 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1299 skip("Failed to create a 3D device, skipping test.\n");
1300 IDirectDraw_Release(ddraw
);
1301 DestroyWindow(window
);
1305 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
1306 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get d3d interface, hr %#x.\n", hr
);
1309 skip("D3D interface is not available, skipping test.\n");
1310 IDirectDraw2_Release(ddraw
);
1313 old_d3d_ref
= get_refcount((IUnknown
*)d3d
);
1315 hr
= IDirect3D2_CreateViewport(d3d
, &viewport2
, NULL
);
1316 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1317 ref
= get_refcount((IUnknown
*)viewport2
);
1318 ok(ref
== 1, "Initial IDirect3DViewport2 refcount is %u\n", ref
);
1319 ref
= get_refcount((IUnknown
*)d3d
);
1320 ok(ref
== old_d3d_ref
, "IDirect3D2 refcount is %u\n", ref
);
1322 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1323 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1324 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
1325 ok(gamma
== NULL
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1326 if (SUCCEEDED(hr
)) IDirectDrawGammaControl_Release(gamma
);
1327 /* NULL iid: Segfaults */
1329 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport
, (void **)&viewport
);
1330 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport, hr %#x.\n", hr
);
1333 ref
= get_refcount((IUnknown
*)viewport
);
1334 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
1335 ref
= get_refcount((IUnknown
*)viewport2
);
1336 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
1337 IDirect3DViewport_Release(viewport
);
1341 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport3
, (void **)&viewport3
);
1342 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to QI IDirect3DViewport3, hr %#x.\n", hr
);
1345 ref
= get_refcount((IUnknown
*)viewport2
);
1346 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
1347 ref
= get_refcount((IUnknown
*)viewport3
);
1348 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1349 IDirect3DViewport3_Release(viewport3
);
1352 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IUnknown
, (void **)&unknown
);
1353 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#x.\n", hr
);
1356 ref
= get_refcount((IUnknown
*)viewport2
);
1357 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
1358 ref
= get_refcount(unknown
);
1359 ok(ref
== 2, "IUnknown refcount is %u\n", ref
);
1360 IUnknown_Release(unknown
);
1363 /* AddViewport(NULL): Segfault */
1364 hr
= IDirect3DDevice2_DeleteViewport(device
, NULL
);
1365 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1366 hr
= IDirect3DDevice2_GetCurrentViewport(device
, NULL
);
1367 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1369 hr
= IDirect3D2_CreateViewport(d3d
, &another_vp
, NULL
);
1370 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1372 /* Setting a viewport not in the viewport list fails */
1373 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1374 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1376 hr
= IDirect3DDevice2_AddViewport(device
, viewport2
);
1377 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1378 ref
= get_refcount((IUnknown
*) viewport2
);
1379 ok(ref
== 2, "viewport2 refcount is %d\n", ref
);
1380 hr
= IDirect3DDevice2_AddViewport(device
, another_vp
);
1381 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1382 ref
= get_refcount((IUnknown
*) another_vp
);
1383 ok(ref
== 2, "another_vp refcount is %d\n", ref
);
1385 test_vp
= (IDirect3DViewport2
*) 0xbaadc0de;
1386 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1387 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1388 ok(test_vp
== (IDirect3DViewport2
*) 0xbaadc0de, "Got unexpected pointer %p\n", test_vp
);
1390 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1391 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1392 ref
= get_refcount((IUnknown
*) viewport2
);
1393 ok(ref
== 3, "viewport2 refcount is %d\n", ref
);
1394 ref
= get_refcount((IUnknown
*) device
);
1395 ok(ref
== 1, "device refcount is %d\n", ref
);
1398 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1399 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1400 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1401 ref
= get_refcount((IUnknown
*) viewport2
);
1402 ok(ref
== 4, "viewport2 refcount is %d\n", ref
);
1403 if(test_vp
) IDirect3DViewport2_Release(test_vp
);
1405 /* GetCurrentViewport with a viewport set and NULL input param: Segfault */
1407 /* Cannot set the viewport to NULL */
1408 hr
= IDirect3DDevice2_SetCurrentViewport(device
, NULL
);
1409 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to set viewport to NULL, hr %#x.\n", hr
);
1411 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1412 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1413 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1414 if(test_vp
) IDirect3DViewport2_Release(test_vp
);
1416 /* SetCurrentViewport properly releases the old viewport's reference */
1417 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1418 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1419 ref
= get_refcount((IUnknown
*) viewport2
);
1420 ok(ref
== 2, "viewport2 refcount is %d\n", ref
);
1421 ref
= get_refcount((IUnknown
*) another_vp
);
1422 ok(ref
== 3, "another_vp refcount is %d\n", ref
);
1424 /* Deleting the viewport removes the reference added by AddViewport, but not
1425 * the one added by SetCurrentViewport. */
1426 hr
= IDirect3DDevice2_DeleteViewport(device
, another_vp
);
1427 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#x.\n", hr
);
1428 ref
= get_refcount((IUnknown
*) another_vp
);
1429 todo_wine
ok(ref
== 2, "IDirect3DViewport2 refcount is %d\n", ref
);
1431 /* GetCurrentViewport fails though */
1433 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1434 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1435 ok(test_vp
== NULL
, "Got unexpected viewport %p\n", test_vp
);
1436 if(test_vp
) IDirect3DViewport2_Release(test_vp
);
1438 /* Setting a different viewport does not free the leaked reference. How
1439 * do I get rid of it? Leak the viewport for now. */
1440 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1441 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1442 ref
= get_refcount((IUnknown
*) viewport2
);
1443 ok(ref
== 3, "viewport2 refcount is %d\n", ref
);
1444 ref
= get_refcount((IUnknown
*) another_vp
);
1445 todo_wine
ok(ref
== 2, "another_vp refcount is %d\n", ref
);
1447 /* Destroying the device removes the viewport, but does not free the reference
1448 * added by SetCurrentViewport. */
1449 IDirect3DDevice2_Release(device
);
1450 ref
= get_refcount((IUnknown
*) viewport2
);
1451 todo_wine
ok(ref
== 2, "viewport2 refcount is %d\n", ref
);
1453 IDirect3DViewport2_Release(another_vp
);
1454 IDirect3DViewport2_Release(viewport2
);
1455 IDirect3D2_Release(d3d
);
1456 DestroyWindow(window
);
1457 IDirectDraw2_Release(ddraw
);
1460 static void test_zenable(void)
1462 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1463 static D3DTLVERTEX tquad
[] =
1465 {{ 0.0f
}, {480.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1466 {{ 0.0f
}, { 0.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1467 {{640.0f
}, {480.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1468 {{640.0f
}, { 0.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1470 IDirect3DMaterial2
*background
;
1471 IDirect3DViewport2
*viewport
;
1472 IDirect3DDevice2
*device
;
1473 IDirectDrawSurface
*rt
;
1474 IDirectDraw2
*ddraw
;
1481 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1482 0, 0, 640, 480, 0, 0, 0, 0);
1483 ddraw
= create_ddraw();
1484 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1485 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1487 skip("Failed to create a 3D device, skipping test.\n");
1488 IDirectDraw2_Release(ddraw
);
1489 DestroyWindow(window
);
1493 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1494 viewport
= create_viewport(device
, 0, 0, 640, 480);
1495 viewport_set_background(device
, viewport
, background
);
1496 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1497 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1499 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1500 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
1502 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1503 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1504 hr
= IDirect3DDevice2_BeginScene(device
);
1505 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1506 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, tquad
, 4, 0);
1507 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1508 hr
= IDirect3DDevice2_EndScene(device
);
1509 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1511 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1512 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1513 for (i
= 0; i
< 4; ++i
)
1515 for (j
= 0; j
< 4; ++j
)
1517 x
= 80 * ((2 * j
) + 1);
1518 y
= 60 * ((2 * i
) + 1);
1519 color
= get_surface_color(rt
, x
, y
);
1520 ok(compare_color(color
, 0x0000ff00, 1),
1521 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1524 IDirectDrawSurface_Release(rt
);
1526 destroy_viewport(device
, viewport
);
1527 destroy_material(background
);
1528 IDirect3DDevice2_Release(device
);
1529 IDirectDraw2_Release(ddraw
);
1530 DestroyWindow(window
);
1533 static void test_ck_rgba(void)
1535 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1536 static D3DTLVERTEX tquad
[] =
1538 {{ 0.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1539 {{ 0.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1540 {{640.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1541 {{640.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1542 {{ 0.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1543 {{ 0.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1544 {{640.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1545 {{640.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1549 D3DCOLOR fill_color
;
1552 D3DCOLOR result1
, result1_broken
;
1553 D3DCOLOR result2
, result2_broken
;
1557 /* r200 on Windows doesn't check the alpha component when applying the color
1558 * key, so the key matches on every texel. */
1559 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1560 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1561 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1562 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1563 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00ff0000, 0x00807f00, 0x000000ff},
1564 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000, 0x0000ff00, 0x000000ff},
1565 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00, 0x00807f00, 0x00807f00},
1566 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1569 D3DTEXTUREHANDLE texture_handle
;
1570 IDirect3DMaterial2
*background
;
1571 IDirectDrawSurface
*surface
;
1572 IDirect3DViewport2
*viewport
;
1573 IDirect3DTexture2
*texture
;
1574 DDSURFACEDESC surface_desc
;
1575 IDirect3DDevice2
*device
;
1576 IDirectDrawSurface
*rt
;
1577 IDirectDraw2
*ddraw
;
1584 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1585 0, 0, 640, 480, 0, 0, 0, 0);
1586 ddraw
= create_ddraw();
1587 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1588 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1590 skip("Failed to create a 3D device, skipping test.\n");
1591 IDirectDraw2_Release(ddraw
);
1592 DestroyWindow(window
);
1596 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1597 viewport
= create_viewport(device
, 0, 0, 640, 480);
1598 viewport_set_background(device
, viewport
, background
);
1599 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1600 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1602 memset(&surface_desc
, 0, sizeof(surface_desc
));
1603 surface_desc
.dwSize
= sizeof(surface_desc
);
1604 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1605 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1606 surface_desc
.dwWidth
= 256;
1607 surface_desc
.dwHeight
= 256;
1608 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1609 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1610 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1611 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1612 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1613 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1614 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1615 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1616 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1617 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1618 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1619 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1620 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1621 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
1622 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1623 IDirect3DTexture2_Release(texture
);
1625 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1626 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1627 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1628 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1629 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1630 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1632 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1633 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1635 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
1637 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1638 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1639 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1640 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1642 memset(&fx
, 0, sizeof(fx
));
1643 fx
.dwSize
= sizeof(fx
);
1644 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1645 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1646 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1648 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
1649 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1650 hr
= IDirect3DDevice2_BeginScene(device
);
1651 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1652 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
1653 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1654 hr
= IDirect3DDevice2_EndScene(device
);
1655 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1657 color
= get_surface_color(rt
, 320, 240);
1658 ok(compare_color(color
, tests
[i
].result1
, 1) || compare_color(color
, tests
[i
].result1_broken
, 1),
1659 "Expected color 0x%08x for test %u, got 0x%08x.\n",
1660 tests
[i
].result1
, i
, color
);
1662 U5(fx
).dwFillColor
= 0xff0000ff;
1663 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1664 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1666 hr
= IDirect3DDevice2_BeginScene(device
);
1667 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1668 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[4], 4, 0);
1669 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1670 hr
= IDirect3DDevice2_EndScene(device
);
1671 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1673 /* This tests that fragments that are masked out by the color key are
1674 * discarded, instead of just fully transparent. */
1675 color
= get_surface_color(rt
, 320, 240);
1676 ok(compare_color(color
, tests
[i
].result2
, 1) || compare_color(color
, tests
[i
].result2_broken
, 1),
1677 "Expected color 0x%08x for test %u, got 0x%08x.\n",
1678 tests
[i
].result2
, i
, color
);
1681 IDirectDrawSurface_Release(rt
);
1682 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1683 ok(SUCCEEDED(hr
), "Failed to unset texture, hr %#x.\n", hr
);
1684 IDirectDrawSurface_Release(surface
);
1685 destroy_viewport(device
, viewport
);
1686 destroy_material(background
);
1687 IDirect3DDevice2_Release(device
);
1688 IDirectDraw2_Release(ddraw
);
1689 DestroyWindow(window
);
1692 static void test_ck_default(void)
1694 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1695 static D3DTLVERTEX tquad
[] =
1697 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1698 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1699 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1700 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1702 IDirectDrawSurface
*surface
, *rt
;
1703 D3DTEXTUREHANDLE texture_handle
;
1704 IDirect3DMaterial2
*background
;
1705 IDirect3DViewport2
*viewport
;
1706 DDSURFACEDESC surface_desc
;
1707 IDirect3DTexture2
*texture
;
1708 IDirect3DDevice2
*device
;
1709 IDirectDraw2
*ddraw
;
1716 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1717 0, 0, 640, 480, 0, 0, 0, 0);
1718 ddraw
= create_ddraw();
1719 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1720 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1722 skip("Failed to create a 3D device, skipping test.\n");
1723 IDirectDraw2_Release(ddraw
);
1724 DestroyWindow(window
);
1728 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1729 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1731 background
= create_diffuse_material(device
, 0.0, 1.0f
, 0.0f
, 1.0f
);
1732 viewport
= create_viewport(device
, 0, 0, 640, 480);
1733 viewport_set_background(device
, viewport
, background
);
1734 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1735 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1737 memset(&surface_desc
, 0, sizeof(surface_desc
));
1738 surface_desc
.dwSize
= sizeof(surface_desc
);
1739 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1740 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1741 surface_desc
.dwWidth
= 256;
1742 surface_desc
.dwHeight
= 256;
1743 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1744 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1745 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1746 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1747 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1748 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1749 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
1750 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
1751 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1752 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1753 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1754 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1755 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
1756 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1757 IDirect3DTexture_Release(texture
);
1759 memset(&fx
, 0, sizeof(fx
));
1760 fx
.dwSize
= sizeof(fx
);
1761 U5(fx
).dwFillColor
= 0x000000ff;
1762 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1763 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
1765 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1766 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1767 hr
= IDirect3DDevice2_BeginScene(device
);
1768 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1769 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1770 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
1771 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1772 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1773 ok(!value
, "Got unexpected color keying state %#x.\n", value
);
1774 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
1775 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1776 hr
= IDirect3DDevice2_EndScene(device
);
1777 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1778 color
= get_surface_color(rt
, 320, 240);
1779 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1781 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1782 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1783 hr
= IDirect3DDevice2_BeginScene(device
);
1784 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1785 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
1786 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1787 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
1788 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1789 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1790 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1791 ok(!!value
, "Got unexpected color keying state %#x.\n", value
);
1792 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1793 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
1794 hr
= IDirect3DDevice2_EndScene(device
);
1795 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1796 color
= get_surface_color(rt
, 320, 240);
1797 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1799 IDirectDrawSurface_Release(surface
);
1800 destroy_viewport(device
, viewport
);
1801 destroy_material(background
);
1802 IDirectDrawSurface_Release(rt
);
1803 IDirect3DDevice2_Release(device
);
1804 IDirectDraw2_Release(ddraw
);
1805 DestroyWindow(window
);
1808 static void test_ck_complex(void)
1810 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
1811 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
1812 DDSURFACEDESC surface_desc
;
1813 IDirect3DDevice2
*device
;
1814 DDCOLORKEY color_key
;
1815 IDirectDraw2
*ddraw
;
1821 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1822 0, 0, 640, 480, 0, 0, 0, 0);
1823 ddraw
= create_ddraw();
1824 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1825 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
1827 skip("Failed to create a 3D device, skipping test.\n");
1828 DestroyWindow(window
);
1829 IDirectDraw2_Release(ddraw
);
1832 IDirect3DDevice2_Release(device
);
1834 memset(&surface_desc
, 0, sizeof(surface_desc
));
1835 surface_desc
.dwSize
= sizeof(surface_desc
);
1836 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1837 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
1838 surface_desc
.dwWidth
= 128;
1839 surface_desc
.dwHeight
= 128;
1840 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1841 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1843 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1844 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1845 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1846 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1847 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1848 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1849 memset(&color_key
, 0, sizeof(color_key
));
1850 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1851 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1852 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1853 color_key
.dwColorSpaceLowValue
);
1854 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1855 color_key
.dwColorSpaceHighValue
);
1858 IDirectDrawSurface_AddRef(mipmap
);
1859 for (i
= 0; i
< 7; ++i
)
1861 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
1862 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
1864 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1865 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
1866 color_key
.dwColorSpaceLowValue
= 0x000000ff;
1867 color_key
.dwColorSpaceHighValue
= 0x000000ff;
1868 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1869 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x, i %u.\n", hr
, i
);
1870 memset(&color_key
, 0, sizeof(color_key
));
1871 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1872 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x, i %u.\n", hr
, i
);
1873 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
1874 color_key
.dwColorSpaceLowValue
, i
);
1875 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
1876 color_key
.dwColorSpaceHighValue
, i
);
1878 IDirectDrawSurface_Release(mipmap
);
1882 memset(&color_key
, 0, sizeof(color_key
));
1883 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1884 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1885 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1886 color_key
.dwColorSpaceLowValue
);
1887 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1888 color_key
.dwColorSpaceHighValue
);
1890 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
1891 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
1892 IDirectDrawSurface_Release(mipmap
);
1893 refcount
= IDirectDrawSurface_Release(surface
);
1894 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1896 memset(&surface_desc
, 0, sizeof(surface_desc
));
1897 surface_desc
.dwSize
= sizeof(surface_desc
);
1898 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
1899 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
1900 surface_desc
.dwBackBufferCount
= 1;
1901 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1902 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1904 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1905 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1906 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1907 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1908 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1909 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1910 memset(&color_key
, 0, sizeof(color_key
));
1911 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1912 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1913 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1914 color_key
.dwColorSpaceLowValue
);
1915 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1916 color_key
.dwColorSpaceHighValue
);
1918 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
1919 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
1921 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1922 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
1923 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1924 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1925 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1926 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1927 memset(&color_key
, 0, sizeof(color_key
));
1928 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1929 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1930 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1931 color_key
.dwColorSpaceLowValue
);
1932 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1933 color_key
.dwColorSpaceHighValue
);
1935 IDirectDrawSurface_Release(tmp
);
1937 refcount
= IDirectDrawSurface_Release(surface
);
1938 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1939 refcount
= IDirectDraw2_Release(ddraw
);
1940 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1941 DestroyWindow(window
);
1947 REFIID refcount_iid
;
1951 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
1952 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
1954 ULONG refcount
, expected_refcount
;
1955 IUnknown
*iface1
, *iface2
;
1959 for (i
= 0; i
< entry_count
; ++i
)
1961 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
1962 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
1965 for (j
= 0; j
< entry_count
; ++j
)
1967 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
1968 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
1971 expected_refcount
= 0;
1972 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
1973 ++expected_refcount
;
1974 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
1975 ++expected_refcount
;
1976 refcount
= IUnknown_Release(iface2
);
1977 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
1978 refcount
, test_name
, i
, j
, expected_refcount
);
1982 expected_refcount
= 0;
1983 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
1984 ++expected_refcount
;
1985 refcount
= IUnknown_Release(iface1
);
1986 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
1987 refcount
, test_name
, i
, expected_refcount
);
1992 static void test_surface_qi(void)
1994 static const struct qi_test tests
[] =
1996 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
1997 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
1998 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
1999 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2000 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2001 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2002 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2003 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2004 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2005 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2006 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2007 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2008 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2009 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2010 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2011 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2012 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2013 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2014 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2015 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2016 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2017 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2018 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2019 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2020 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2021 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2022 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2023 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2024 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2025 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2026 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2027 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2028 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2029 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2030 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2033 IDirectDrawSurface
*surface
;
2034 DDSURFACEDESC surface_desc
;
2035 IDirect3DDevice2
*device
;
2036 IDirectDraw2
*ddraw
;
2040 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2042 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2046 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2047 0, 0, 640, 480, 0, 0, 0, 0);
2048 ddraw
= create_ddraw();
2049 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2050 /* Try to create a D3D device to see if the ddraw implementation supports
2051 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
2052 * doesn't support e.g. the IDirect3DTexture interfaces. */
2053 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2055 skip("Failed to create a 3D device, skipping test.\n");
2056 IDirectDraw2_Release(ddraw
);
2057 DestroyWindow(window
);
2060 IDirect3DDevice_Release(device
);
2062 memset(&surface_desc
, 0, sizeof(surface_desc
));
2063 surface_desc
.dwSize
= sizeof(surface_desc
);
2064 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2065 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2066 surface_desc
.dwWidth
= 512;
2067 surface_desc
.dwHeight
= 512;
2068 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2069 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2071 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface
, tests
, sizeof(tests
) / sizeof(*tests
));
2073 IDirectDrawSurface_Release(surface
);
2074 IDirectDraw2_Release(ddraw
);
2075 DestroyWindow(window
);
2078 static void test_device_qi(void)
2080 static const struct qi_test tests
[] =
2082 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
2083 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
2084 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
2085 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2086 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
2087 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
2088 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
2089 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
2090 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
2091 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
2092 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
2093 {&IID_IDirect3DDevice2
, &IID_IDirect3DDevice2
, S_OK
},
2094 {&IID_IDirect3DDevice
, &IID_IDirect3DDevice2
, S_OK
},
2095 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
2096 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
2097 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
2098 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
2099 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
2100 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
2101 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
2102 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
2103 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
2104 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
2105 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
2106 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
2107 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
2108 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
2109 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
2110 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
2111 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
2112 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
2113 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
2114 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
2115 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
2116 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
2117 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
2118 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
2119 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
2120 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
2121 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
2122 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
2123 {&IID_IUnknown
, &IID_IDirect3DDevice2
, S_OK
},
2126 IDirect3DDevice2
*device
;
2127 IDirectDraw2
*ddraw
;
2130 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2131 0, 0, 640, 480, 0, 0, 0, 0);
2132 ddraw
= create_ddraw();
2133 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2134 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2136 skip("Failed to create a 3D device, skipping test.\n");
2137 IDirectDraw2_Release(ddraw
);
2138 DestroyWindow(window
);
2142 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice2
, tests
, sizeof(tests
) / sizeof(*tests
));
2144 IDirect3DDevice2_Release(device
);
2145 IDirectDraw2_Release(ddraw
);
2146 DestroyWindow(window
);
2149 static void test_wndproc(void)
2151 LONG_PTR proc
, ddraw_proc
;
2152 IDirectDraw2
*ddraw
;
2158 static struct message messages
[] =
2160 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2161 {WM_MOVE
, FALSE
, 0},
2162 {WM_SIZE
, FALSE
, 0},
2163 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2164 {WM_ACTIVATE
, FALSE
, 0},
2165 {WM_SETFOCUS
, FALSE
, 0},
2169 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2170 ddraw
= create_ddraw();
2171 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2173 wc
.lpfnWndProc
= test_proc
;
2174 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2175 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2177 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2178 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2180 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2181 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2182 (LONG_PTR
)test_proc
, proc
);
2183 expect_messages
= messages
;
2184 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2185 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2186 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2187 expect_messages
= NULL
;
2188 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2189 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2190 (LONG_PTR
)test_proc
, proc
);
2191 ref
= IDirectDraw2_Release(ddraw
);
2192 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2193 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2194 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2195 (LONG_PTR
)test_proc
, proc
);
2197 /* DDSCL_NORMAL doesn't. */
2198 ddraw
= create_ddraw();
2199 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2200 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2201 (LONG_PTR
)test_proc
, proc
);
2202 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2203 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2204 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2205 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2206 (LONG_PTR
)test_proc
, proc
);
2207 ref
= IDirectDraw2_Release(ddraw
);
2208 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2209 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2210 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2211 (LONG_PTR
)test_proc
, proc
);
2213 /* The original window proc is only restored by ddraw if the current
2214 * window proc matches the one ddraw set. This also affects switching
2215 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2216 ddraw
= create_ddraw();
2217 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2218 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2219 (LONG_PTR
)test_proc
, proc
);
2220 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2221 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2222 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2223 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2224 (LONG_PTR
)test_proc
, proc
);
2226 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2227 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2228 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2229 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2230 (LONG_PTR
)test_proc
, proc
);
2231 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2232 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2233 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2234 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2235 (LONG_PTR
)test_proc
, proc
);
2236 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2237 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2238 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2239 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2240 (LONG_PTR
)DefWindowProcA
, proc
);
2241 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2242 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2243 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)ddraw_proc
);
2244 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2245 (LONG_PTR
)DefWindowProcA
, proc
);
2246 ref
= IDirectDraw2_Release(ddraw
);
2247 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2248 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2249 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2250 (LONG_PTR
)test_proc
, proc
);
2252 ddraw
= create_ddraw();
2253 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2254 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2255 (LONG_PTR
)test_proc
, proc
);
2256 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2257 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2258 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2259 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2260 (LONG_PTR
)test_proc
, proc
);
2261 ref
= IDirectDraw2_Release(ddraw
);
2262 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2263 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2264 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2265 (LONG_PTR
)DefWindowProcA
, proc
);
2267 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2268 expect_messages
= NULL
;
2269 DestroyWindow(window
);
2270 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2273 static void test_window_style(void)
2275 LONG style
, exstyle
, tmp
, expected_style
;
2276 RECT fullscreen_rect
, r
;
2277 IDirectDraw2
*ddraw
;
2283 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2284 0, 0, 100, 100, 0, 0, 0, 0);
2285 ddraw
= create_ddraw();
2286 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2288 style
= GetWindowLongA(window
, GWL_STYLE
);
2289 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2290 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2292 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2293 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2295 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2296 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2297 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2298 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2300 GetWindowRect(window
, &r
);
2301 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2302 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2303 GetClientRect(window
, &r
);
2304 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2306 ret
= SetForegroundWindow(GetDesktopWindow());
2307 ok(ret
, "Failed to set foreground window.\n");
2309 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2310 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2311 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2312 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2314 ret
= SetForegroundWindow(window
);
2315 ok(ret
, "Failed to set foreground window.\n");
2316 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2317 * the next tests expect this. */
2318 ShowWindow(window
, SW_HIDE
);
2320 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2321 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2323 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2324 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2325 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2326 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2328 ShowWindow(window
, SW_SHOW
);
2329 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2330 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2332 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2333 expected_style
= style
| WS_VISIBLE
;
2334 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2335 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2336 expected_style
= exstyle
| WS_EX_TOPMOST
;
2337 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2339 ret
= SetForegroundWindow(GetDesktopWindow());
2340 ok(ret
, "Failed to set foreground window.\n");
2341 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2342 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
2343 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2344 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2345 expected_style
= exstyle
| WS_EX_TOPMOST
;
2346 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2348 ref
= IDirectDraw2_Release(ddraw
);
2349 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2351 DestroyWindow(window
);
2354 static void test_redundant_mode_set(void)
2356 DDSURFACEDESC surface_desc
= {0};
2357 IDirectDraw2
*ddraw
;
2363 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2364 0, 0, 100, 100, 0, 0, 0, 0);
2365 ddraw
= create_ddraw();
2366 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2368 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2369 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2371 surface_desc
.dwSize
= sizeof(surface_desc
);
2372 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
2373 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
2375 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2376 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2377 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2379 GetWindowRect(window
, &r
);
2382 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2383 GetWindowRect(window
, &s
);
2384 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2386 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2387 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2388 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2390 GetWindowRect(window
, &s
);
2391 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2393 ref
= IDirectDraw2_Release(ddraw
);
2394 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2396 DestroyWindow(window
);
2399 static SIZE screen_size
, screen_size2
;
2401 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2403 if (message
== WM_SIZE
)
2405 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2406 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2409 return test_proc(hwnd
, message
, wparam
, lparam
);
2412 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2414 if (message
== WM_SIZE
)
2416 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2417 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2420 return test_proc(hwnd
, message
, wparam
, lparam
);
2423 struct test_coop_level_mode_set_enum_param
2425 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
2428 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC
*surface_desc
, void *context
)
2430 struct test_coop_level_mode_set_enum_param
*param
= context
;
2432 if (U1(surface_desc
->ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
2433 return DDENUMRET_OK
;
2434 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
2435 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
2436 return DDENUMRET_OK
;
2438 if (!param
->ddraw_width
)
2440 param
->ddraw_width
= surface_desc
->dwWidth
;
2441 param
->ddraw_height
= surface_desc
->dwHeight
;
2442 return DDENUMRET_OK
;
2444 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
2445 return DDENUMRET_OK
;
2447 param
->user32_width
= surface_desc
->dwWidth
;
2448 param
->user32_height
= surface_desc
->dwHeight
;
2449 return DDENUMRET_CANCEL
;
2452 static void test_coop_level_mode_set(void)
2454 IDirectDrawSurface
*primary
;
2455 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
2456 IDirectDraw2
*ddraw
;
2459 HWND window
, window2
;
2463 struct test_coop_level_mode_set_enum_param param
;
2468 static const struct message exclusive_messages
[] =
2470 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2471 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2472 {WM_SIZE
, FALSE
, 0},
2473 {WM_DISPLAYCHANGE
, FALSE
, 0},
2476 static const struct message exclusive_focus_loss_messages
[] =
2478 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
},
2479 {WM_DISPLAYCHANGE
, FALSE
, 0},
2480 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2481 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
2482 * SW_MINIMIZED, causing a recursive window activation that does not
2483 * produce the same result in Wine yet. Ignore the difference for now.
2484 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
2485 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2486 {WM_MOVE
, FALSE
, 0},
2487 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2488 {WM_ACTIVATEAPP
, TRUE
, FALSE
},
2491 static const struct message exclusive_focus_restore_messages
[] =
2493 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
2494 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
2495 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
2496 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
2497 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
2498 /* Native redundantly sets the window size here. */
2499 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
2500 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
2501 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
2502 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
2505 static const struct message sc_restore_messages
[] =
2507 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
2508 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2509 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2510 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
2513 static const struct message sc_minimize_messages
[] =
2515 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
2516 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2517 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2518 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2521 static const struct message sc_maximize_messages
[] =
2523 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
2524 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2525 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2526 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
2530 static const struct message normal_messages
[] =
2532 {WM_DISPLAYCHANGE
, FALSE
, 0},
2536 ddraw
= create_ddraw();
2537 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2539 memset(¶m
, 0, sizeof(param
));
2540 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
2541 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#x.\n", hr
);
2542 ref
= IDirectDraw2_Release(ddraw
);
2543 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2545 if (!param
.user32_height
)
2547 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
2551 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2552 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
2553 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
2555 memset(&devmode
, 0, sizeof(devmode
));
2556 devmode
.dmSize
= sizeof(devmode
);
2557 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2558 devmode
.dmPelsWidth
= param
.user32_width
;
2559 devmode
.dmPelsHeight
= param
.user32_height
;
2560 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2561 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2563 ddraw
= create_ddraw();
2564 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2566 wc
.lpfnWndProc
= mode_set_proc
;
2567 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2568 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2569 wc
.lpfnWndProc
= mode_set_proc2
;
2570 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
2571 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2573 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2574 0, 0, 100, 100, 0, 0, 0, 0);
2575 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2576 0, 0, 100, 100, 0, 0, 0, 0);
2578 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2579 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2581 GetWindowRect(window
, &r
);
2582 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2583 wine_dbgstr_rect(&r
));
2585 memset(&ddsd
, 0, sizeof(ddsd
));
2586 ddsd
.dwSize
= sizeof(ddsd
);
2587 ddsd
.dwFlags
= DDSD_CAPS
;
2588 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2590 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2591 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2592 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2593 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2594 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2595 param
.user32_width
, ddsd
.dwWidth
);
2596 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2597 param
.user32_height
, ddsd
.dwHeight
);
2599 GetWindowRect(window
, &r
);
2600 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2601 wine_dbgstr_rect(&r
));
2603 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2604 expect_messages
= exclusive_messages
;
2608 hr
= IDirectDrawSurface_IsLost(primary
);
2609 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2610 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
2611 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2612 hr
= IDirectDrawSurface_IsLost(primary
);
2613 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2615 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2616 expect_messages
= NULL
;
2617 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
2618 "Expected screen size %ux%u, got %ux%u.\n",
2619 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
2621 GetWindowRect(window
, &r
);
2622 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2623 wine_dbgstr_rect(&r
));
2625 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2626 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2627 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2628 param
.user32_width
, ddsd
.dwWidth
);
2629 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2630 param
.user32_height
, ddsd
.dwHeight
);
2631 IDirectDrawSurface_Release(primary
);
2633 memset(&ddsd
, 0, sizeof(ddsd
));
2634 ddsd
.dwSize
= sizeof(ddsd
);
2635 ddsd
.dwFlags
= DDSD_CAPS
;
2636 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2638 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2639 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2640 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2641 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2642 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2643 param
.ddraw_width
, ddsd
.dwWidth
);
2644 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2645 param
.ddraw_height
, ddsd
.dwHeight
);
2647 GetWindowRect(window
, &r
);
2648 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2649 wine_dbgstr_rect(&r
));
2651 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2652 expect_messages
= exclusive_messages
;
2656 hr
= IDirectDrawSurface_IsLost(primary
);
2657 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2658 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2659 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2660 hr
= IDirectDrawSurface_IsLost(primary
);
2661 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2663 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2664 expect_messages
= NULL
;
2665 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
2666 "Expected screen size %ux%u, got %ux%u.\n",
2667 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
2669 GetWindowRect(window
, &r
);
2670 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2671 wine_dbgstr_rect(&r
));
2673 expect_messages
= exclusive_focus_loss_messages
;
2674 ret
= SetForegroundWindow(GetDesktopWindow());
2675 ok(ret
, "Failed to set foreground window.\n");
2676 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2677 memset(&devmode
, 0, sizeof(devmode
));
2678 devmode
.dmSize
= sizeof(devmode
);
2679 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2680 ok(ret
, "Failed to get display mode.\n");
2681 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
2682 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpect screen size %ux%u.\n",
2683 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2685 expect_messages
= exclusive_focus_restore_messages
;
2686 ShowWindow(window
, SW_RESTORE
);
2687 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2689 GetWindowRect(window
, &r
);
2690 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2691 wine_dbgstr_rect(&r
));
2692 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2693 ok(ret
, "Failed to get display mode.\n");
2694 ok(devmode
.dmPelsWidth
== param
.ddraw_width
2695 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpect screen size %ux%u.\n",
2696 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2698 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2699 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2700 /* Normally the primary should be restored here. Unfortunately this causes the
2701 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
2702 * testbot. Another Restore call would presumably avoid the crash, but it also moots
2703 * the point of the GetSurfaceDesc call. */
2705 expect_messages
= sc_minimize_messages
;
2706 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
2707 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2708 expect_messages
= NULL
;
2710 expect_messages
= sc_restore_messages
;
2711 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
2712 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2713 expect_messages
= NULL
;
2715 expect_messages
= sc_maximize_messages
;
2716 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
2717 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2718 expect_messages
= NULL
;
2720 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2721 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2723 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2724 expect_messages
= exclusive_messages
;
2728 hr
= IDirectDrawSurface_IsLost(primary
);
2729 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2730 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
2731 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2732 hr
= IDirectDrawSurface_IsLost(primary
);
2733 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2735 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2736 expect_messages
= NULL
;
2737 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
2738 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
2739 "Expected screen size %ux%u, got %ux%u.\n",
2740 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
2742 GetWindowRect(window
, &r
);
2743 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2744 wine_dbgstr_rect(&r
));
2746 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2747 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2748 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2749 param
.ddraw_width
, ddsd
.dwWidth
);
2750 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2751 param
.ddraw_height
, ddsd
.dwHeight
);
2752 IDirectDrawSurface_Release(primary
);
2755 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
2756 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2758 memset(&ddsd
, 0, sizeof(ddsd
));
2759 ddsd
.dwSize
= sizeof(ddsd
);
2760 ddsd
.dwFlags
= DDSD_CAPS
;
2761 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2763 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2764 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2765 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2766 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2767 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2768 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2769 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2770 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2772 GetWindowRect(window
, &r
);
2773 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2774 wine_dbgstr_rect(&r
));
2776 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2777 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2779 GetWindowRect(window
, &r
);
2780 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2781 wine_dbgstr_rect(&r
));
2783 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2784 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2785 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2786 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2787 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2788 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2789 IDirectDrawSurface_Release(primary
);
2791 memset(&ddsd
, 0, sizeof(ddsd
));
2792 ddsd
.dwSize
= sizeof(ddsd
);
2793 ddsd
.dwFlags
= DDSD_CAPS
;
2794 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2796 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2797 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2798 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2799 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2800 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2801 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2802 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2803 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2805 GetWindowRect(window
, &r
);
2806 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2807 wine_dbgstr_rect(&r
));
2809 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2810 expect_messages
= normal_messages
;
2814 hr
= IDirectDrawSurface_IsLost(primary
);
2815 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2816 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2817 devmode
.dmPelsWidth
= param
.user32_width
;
2818 devmode
.dmPelsHeight
= param
.user32_height
;
2819 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2820 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2821 hr
= IDirectDrawSurface_IsLost(primary
);
2822 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2824 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2825 expect_messages
= NULL
;
2826 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2828 GetWindowRect(window
, &r
);
2829 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2830 wine_dbgstr_rect(&r
));
2832 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2833 expect_messages
= normal_messages
;
2837 hr
= IDirectDrawSurface_Restore(primary
);
2838 todo_wine
ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
2839 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
2840 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
2842 win_skip("Broken SetDisplayMode(), skipping remaining tests.\n");
2843 IDirectDrawSurface_Release(primary
);
2844 IDirectDraw2_Release(ddraw
);
2847 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2848 hr
= IDirectDrawSurface_Restore(primary
);
2849 todo_wine
ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
2850 hr
= IDirectDrawSurface_IsLost(primary
);
2851 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2853 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2854 expect_messages
= NULL
;
2855 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2857 GetWindowRect(window
, &r
);
2858 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2859 wine_dbgstr_rect(&r
));
2861 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2862 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2863 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2864 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2865 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2866 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2867 IDirectDrawSurface_Release(primary
);
2869 memset(&ddsd
, 0, sizeof(ddsd
));
2870 ddsd
.dwSize
= sizeof(ddsd
);
2871 ddsd
.dwFlags
= DDSD_CAPS
;
2872 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2874 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2875 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2876 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2877 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2878 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2879 param
.ddraw_width
, ddsd
.dwWidth
);
2880 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2881 param
.ddraw_height
, ddsd
.dwHeight
);
2883 GetWindowRect(window
, &r
);
2884 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2885 wine_dbgstr_rect(&r
));
2887 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2888 expect_messages
= normal_messages
;
2892 hr
= IDirectDrawSurface_IsLost(primary
);
2893 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2894 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2895 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2896 hr
= IDirectDrawSurface_IsLost(primary
);
2897 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2899 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2900 expect_messages
= NULL
;
2901 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2903 GetWindowRect(window
, &r
);
2904 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2905 wine_dbgstr_rect(&r
));
2907 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2908 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2909 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2910 param
.ddraw_width
, ddsd
.dwWidth
);
2911 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2912 param
.ddraw_height
, ddsd
.dwHeight
);
2913 IDirectDrawSurface_Release(primary
);
2915 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2916 ok(ret
, "Failed to get display mode.\n");
2917 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
2918 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
2919 "Expected resolution %ux%u, got %ux%u.\n",
2920 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
2921 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2922 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
2923 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2925 memset(&ddsd
, 0, sizeof(ddsd
));
2926 ddsd
.dwSize
= sizeof(ddsd
);
2927 ddsd
.dwFlags
= DDSD_CAPS
;
2928 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2930 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2931 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2932 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2933 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2934 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2935 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2936 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2937 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2939 GetWindowRect(window
, &r
);
2940 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2941 wine_dbgstr_rect(&r
));
2943 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
2944 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
2945 * not DDSCL_FULLSCREEN. */
2946 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2947 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2949 GetWindowRect(window
, &r
);
2950 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2951 wine_dbgstr_rect(&r
));
2953 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2954 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2955 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2956 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2957 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2958 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2959 IDirectDrawSurface_Release(primary
);
2961 memset(&ddsd
, 0, sizeof(ddsd
));
2962 ddsd
.dwSize
= sizeof(ddsd
);
2963 ddsd
.dwFlags
= DDSD_CAPS
;
2964 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2966 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2967 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2968 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2969 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2970 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2971 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2972 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2973 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2975 GetWindowRect(window
, &r
);
2976 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2977 wine_dbgstr_rect(&r
));
2979 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2980 expect_messages
= normal_messages
;
2984 hr
= IDirectDrawSurface_IsLost(primary
);
2985 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2986 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2987 devmode
.dmPelsWidth
= param
.user32_width
;
2988 devmode
.dmPelsHeight
= param
.user32_height
;
2989 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2990 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2991 hr
= IDirectDrawSurface_IsLost(primary
);
2992 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2994 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2995 expect_messages
= NULL
;
2996 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2998 GetWindowRect(window
, &r
);
2999 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3000 wine_dbgstr_rect(&r
));
3002 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3003 expect_messages
= normal_messages
;
3007 hr
= IDirectDrawSurface_Restore(primary
);
3008 todo_wine
ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3009 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3010 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3011 hr
= IDirectDrawSurface_Restore(primary
);
3012 todo_wine
ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3013 hr
= IDirectDrawSurface_IsLost(primary
);
3014 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3016 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3017 expect_messages
= NULL
;
3018 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3020 GetWindowRect(window
, &r
);
3021 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3022 wine_dbgstr_rect(&r
));
3024 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3025 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3026 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3027 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3028 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3029 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3030 IDirectDrawSurface_Release(primary
);
3032 memset(&ddsd
, 0, sizeof(ddsd
));
3033 ddsd
.dwSize
= sizeof(ddsd
);
3034 ddsd
.dwFlags
= DDSD_CAPS
;
3035 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3037 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3038 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3039 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3040 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3041 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3042 param
.ddraw_width
, ddsd
.dwWidth
);
3043 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3044 param
.ddraw_height
, ddsd
.dwHeight
);
3046 GetWindowRect(window
, &r
);
3047 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3048 wine_dbgstr_rect(&r
));
3050 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3051 expect_messages
= normal_messages
;
3055 hr
= IDirectDrawSurface_IsLost(primary
);
3056 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3057 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3058 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3059 hr
= IDirectDrawSurface_IsLost(primary
);
3060 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3062 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3063 expect_messages
= NULL
;
3064 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3066 GetWindowRect(window
, &r
);
3067 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3068 wine_dbgstr_rect(&r
));
3070 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3071 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3072 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3073 param
.ddraw_width
, ddsd
.dwWidth
);
3074 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3075 param
.ddraw_height
, ddsd
.dwHeight
);
3076 IDirectDrawSurface_Release(primary
);
3078 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3079 ok(ret
, "Failed to get display mode.\n");
3080 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3081 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3082 "Expected resolution %ux%u, got %ux%u.\n",
3083 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3084 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3085 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3086 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3088 memset(&ddsd
, 0, sizeof(ddsd
));
3089 ddsd
.dwSize
= sizeof(ddsd
);
3090 ddsd
.dwFlags
= DDSD_CAPS
;
3091 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3093 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3094 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3095 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3096 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3097 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3098 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3099 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3100 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3101 IDirectDrawSurface_Release(primary
);
3103 GetWindowRect(window
, &r
);
3104 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3105 wine_dbgstr_rect(&r
));
3107 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
3108 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3109 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3110 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3111 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3113 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3114 expect_messages
= exclusive_messages
;
3118 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3119 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3121 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3122 expect_messages
= NULL
;
3123 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3124 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3125 "Expected screen size %ux%u, got %ux%u.\n",
3126 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3127 screen_size
.cx
, screen_size
.cy
);
3129 GetWindowRect(window
, &r
);
3130 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3131 wine_dbgstr_rect(&r
));
3133 memset(&ddsd
, 0, sizeof(ddsd
));
3134 ddsd
.dwSize
= sizeof(ddsd
);
3135 ddsd
.dwFlags
= DDSD_CAPS
;
3136 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3138 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3139 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3140 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3141 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3142 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3143 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3144 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3145 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3146 IDirectDrawSurface_Release(primary
);
3148 /* The screen restore is a property of DDSCL_EXCLUSIVE */
3149 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3150 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3151 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3152 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3154 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3155 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3157 memset(&ddsd
, 0, sizeof(ddsd
));
3158 ddsd
.dwSize
= sizeof(ddsd
);
3159 ddsd
.dwFlags
= DDSD_CAPS
;
3160 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3162 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3163 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3164 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3165 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3166 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3167 param
.ddraw_width
, ddsd
.dwWidth
);
3168 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3169 param
.ddraw_height
, ddsd
.dwHeight
);
3170 IDirectDrawSurface_Release(primary
);
3172 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3173 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3175 /* If the window is changed at the same time, messages are sent to the new window. */
3176 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3177 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3178 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3179 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3181 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3182 expect_messages
= exclusive_messages
;
3185 screen_size2
.cx
= 0;
3186 screen_size2
.cy
= 0;
3188 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3189 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3191 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3192 expect_messages
= NULL
;
3193 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n",
3194 screen_size
.cx
, screen_size
.cy
);
3195 ok(screen_size2
.cx
== registry_mode
.dmPelsWidth
&& screen_size2
.cy
== registry_mode
.dmPelsHeight
,
3196 "Expected screen size 2 %ux%u, got %ux%u.\n",
3197 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size2
.cx
, screen_size2
.cy
);
3199 GetWindowRect(window
, &r
);
3200 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3201 wine_dbgstr_rect(&r
));
3202 GetWindowRect(window2
, &r
);
3203 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3204 wine_dbgstr_rect(&r
));
3206 memset(&ddsd
, 0, sizeof(ddsd
));
3207 ddsd
.dwSize
= sizeof(ddsd
);
3208 ddsd
.dwFlags
= DDSD_CAPS
;
3209 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3211 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3212 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3213 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3214 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3215 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3216 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3217 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3218 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3219 IDirectDrawSurface_Release(primary
);
3221 ref
= IDirectDraw2_Release(ddraw
);
3222 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3224 GetWindowRect(window
, &r
);
3225 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3226 wine_dbgstr_rect(&r
));
3229 expect_messages
= NULL
;
3230 DestroyWindow(window
);
3231 DestroyWindow(window2
);
3232 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3233 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
3236 static void test_coop_level_mode_set_multi(void)
3238 IDirectDraw2
*ddraw1
, *ddraw2
;
3244 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3245 0, 0, 100, 100, 0, 0, 0, 0);
3246 ddraw1
= create_ddraw();
3247 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3249 /* With just a single ddraw object, the display mode is restored on
3251 hr
= set_display_mode(ddraw1
, 800, 600);
3252 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3254 win_skip("Broken SetDisplayMode(), skipping test.\n");
3255 IDirectDraw2_Release(ddraw1
);
3256 DestroyWindow(window
);
3259 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3260 w
= GetSystemMetrics(SM_CXSCREEN
);
3261 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3262 h
= GetSystemMetrics(SM_CYSCREEN
);
3263 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3265 ref
= IDirectDraw2_Release(ddraw1
);
3266 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3267 w
= GetSystemMetrics(SM_CXSCREEN
);
3268 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3269 h
= GetSystemMetrics(SM_CYSCREEN
);
3270 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3272 /* When there are multiple ddraw objects, the display mode is restored to
3273 * the initial mode, before the first SetDisplayMode() call. */
3274 ddraw1
= create_ddraw();
3275 hr
= set_display_mode(ddraw1
, 800, 600);
3276 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3277 w
= GetSystemMetrics(SM_CXSCREEN
);
3278 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3279 h
= GetSystemMetrics(SM_CYSCREEN
);
3280 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3282 ddraw2
= create_ddraw();
3283 hr
= set_display_mode(ddraw2
, 640, 480);
3284 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3285 w
= GetSystemMetrics(SM_CXSCREEN
);
3286 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3287 h
= GetSystemMetrics(SM_CYSCREEN
);
3288 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3290 ref
= IDirectDraw2_Release(ddraw2
);
3291 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3292 w
= GetSystemMetrics(SM_CXSCREEN
);
3293 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3294 h
= GetSystemMetrics(SM_CYSCREEN
);
3295 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3297 ref
= IDirectDraw2_Release(ddraw1
);
3298 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3299 w
= GetSystemMetrics(SM_CXSCREEN
);
3300 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3301 h
= GetSystemMetrics(SM_CYSCREEN
);
3302 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3304 /* Regardless of release ordering. */
3305 ddraw1
= create_ddraw();
3306 hr
= set_display_mode(ddraw1
, 800, 600);
3307 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3308 w
= GetSystemMetrics(SM_CXSCREEN
);
3309 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3310 h
= GetSystemMetrics(SM_CYSCREEN
);
3311 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3313 ddraw2
= create_ddraw();
3314 hr
= set_display_mode(ddraw2
, 640, 480);
3315 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3316 w
= GetSystemMetrics(SM_CXSCREEN
);
3317 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3318 h
= GetSystemMetrics(SM_CYSCREEN
);
3319 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3321 ref
= IDirectDraw2_Release(ddraw1
);
3322 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3323 w
= GetSystemMetrics(SM_CXSCREEN
);
3324 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3325 h
= GetSystemMetrics(SM_CYSCREEN
);
3326 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3328 ref
= IDirectDraw2_Release(ddraw2
);
3329 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3330 w
= GetSystemMetrics(SM_CXSCREEN
);
3331 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3332 h
= GetSystemMetrics(SM_CYSCREEN
);
3333 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3335 /* But only for ddraw objects that called SetDisplayMode(). */
3336 ddraw1
= create_ddraw();
3337 ddraw2
= create_ddraw();
3338 hr
= set_display_mode(ddraw2
, 640, 480);
3339 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3340 w
= GetSystemMetrics(SM_CXSCREEN
);
3341 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3342 h
= GetSystemMetrics(SM_CYSCREEN
);
3343 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3345 ref
= IDirectDraw2_Release(ddraw1
);
3346 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3347 w
= GetSystemMetrics(SM_CXSCREEN
);
3348 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3349 h
= GetSystemMetrics(SM_CYSCREEN
);
3350 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3352 ref
= IDirectDraw2_Release(ddraw2
);
3353 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3354 w
= GetSystemMetrics(SM_CXSCREEN
);
3355 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3356 h
= GetSystemMetrics(SM_CYSCREEN
);
3357 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3359 /* If there's a ddraw object that's currently in exclusive mode, it blocks
3360 * restoring the display mode. */
3361 ddraw1
= create_ddraw();
3362 hr
= set_display_mode(ddraw1
, 800, 600);
3363 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3364 w
= GetSystemMetrics(SM_CXSCREEN
);
3365 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3366 h
= GetSystemMetrics(SM_CYSCREEN
);
3367 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3369 ddraw2
= create_ddraw();
3370 hr
= set_display_mode(ddraw2
, 640, 480);
3371 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3372 w
= GetSystemMetrics(SM_CXSCREEN
);
3373 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3374 h
= GetSystemMetrics(SM_CYSCREEN
);
3375 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3377 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3378 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3380 ref
= IDirectDraw2_Release(ddraw1
);
3381 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3382 w
= GetSystemMetrics(SM_CXSCREEN
);
3383 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3384 h
= GetSystemMetrics(SM_CYSCREEN
);
3385 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3387 ref
= IDirectDraw2_Release(ddraw2
);
3388 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3389 w
= GetSystemMetrics(SM_CXSCREEN
);
3390 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3391 h
= GetSystemMetrics(SM_CYSCREEN
);
3392 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3394 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
3395 ddraw1
= create_ddraw();
3396 hr
= set_display_mode(ddraw1
, 800, 600);
3397 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3398 w
= GetSystemMetrics(SM_CXSCREEN
);
3399 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3400 h
= GetSystemMetrics(SM_CYSCREEN
);
3401 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3403 hr
= IDirectDraw2_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3404 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3406 ddraw2
= create_ddraw();
3407 hr
= set_display_mode(ddraw2
, 640, 480);
3408 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
3410 ref
= IDirectDraw2_Release(ddraw1
);
3411 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3412 w
= GetSystemMetrics(SM_CXSCREEN
);
3413 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3414 h
= GetSystemMetrics(SM_CYSCREEN
);
3415 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3417 ref
= IDirectDraw2_Release(ddraw2
);
3418 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3419 w
= GetSystemMetrics(SM_CXSCREEN
);
3420 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3421 h
= GetSystemMetrics(SM_CYSCREEN
);
3422 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3424 DestroyWindow(window
);
3427 static void test_initialize(void)
3429 IDirectDraw2
*ddraw
;
3432 ddraw
= create_ddraw();
3433 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3435 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
3436 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
3437 IDirectDraw2_Release(ddraw
);
3440 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw2
, (void **)&ddraw
);
3441 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr
);
3442 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
3443 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
3444 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
3445 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
3446 IDirectDraw2_Release(ddraw
);
3450 static void test_coop_level_surf_create(void)
3452 IDirectDrawSurface
*surface
;
3453 IDirectDraw2
*ddraw
;
3457 ddraw
= create_ddraw();
3458 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3460 memset(&ddsd
, 0, sizeof(ddsd
));
3461 ddsd
.dwSize
= sizeof(ddsd
);
3462 ddsd
.dwFlags
= DDSD_CAPS
;
3463 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3464 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3465 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
3467 IDirectDraw2_Release(ddraw
);
3470 static void test_coop_level_multi_window(void)
3472 HWND window1
, window2
;
3473 IDirectDraw2
*ddraw
;
3476 window1
= CreateWindowA("static", "ddraw_test1", WS_OVERLAPPEDWINDOW
,
3477 0, 0, 640, 480, 0, 0, 0, 0);
3478 window2
= CreateWindowA("static", "ddraw_test2", WS_OVERLAPPEDWINDOW
,
3479 0, 0, 640, 480, 0, 0, 0, 0);
3480 ddraw
= create_ddraw();
3481 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3483 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
3484 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3485 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3486 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3487 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
3488 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
3490 IDirectDraw2_Release(ddraw
);
3491 DestroyWindow(window2
);
3492 DestroyWindow(window1
);
3495 static void test_clear_rect_count(void)
3497 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3498 IDirect3DMaterial2
*white
, *red
, *green
, *blue
;
3499 IDirect3DViewport2
*viewport
;
3500 IDirect3DDevice2
*device
;
3501 IDirectDrawSurface
*rt
;
3502 IDirectDraw2
*ddraw
;
3507 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3508 0, 0, 640, 480, 0, 0, 0, 0);
3509 ddraw
= create_ddraw();
3510 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3511 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3513 skip("Failed to create a 3D device, skipping test.\n");
3514 IDirectDraw2_Release(ddraw
);
3515 DestroyWindow(window
);
3519 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
3520 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3522 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
3523 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
3524 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
3525 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
3527 viewport
= create_viewport(device
, 0, 0, 640, 480);
3528 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
3529 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
3531 viewport_set_background(device
, viewport
, white
);
3532 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
3533 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3534 viewport_set_background(device
, viewport
, red
);
3535 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
3536 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3537 viewport_set_background(device
, viewport
, green
);
3538 hr
= IDirect3DViewport2_Clear(viewport
, 0, NULL
, D3DCLEAR_TARGET
);
3539 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3540 viewport_set_background(device
, viewport
, blue
);
3541 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
3542 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3544 color
= get_surface_color(rt
, 320, 240);
3545 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x000000ff, 1)),
3546 "Got unexpected color 0x%08x.\n", color
);
3548 IDirectDrawSurface_Release(rt
);
3549 destroy_viewport(device
, viewport
);
3550 destroy_material(white
);
3551 destroy_material(red
);
3552 destroy_material(green
);
3553 destroy_material(blue
);
3554 IDirect3DDevice2_Release(device
);
3555 IDirectDraw2_Release(ddraw
);
3556 DestroyWindow(window
);
3559 static BOOL
test_mode_restored(IDirectDraw2
*ddraw
, HWND window
)
3561 DDSURFACEDESC ddsd1
, ddsd2
;
3564 memset(&ddsd1
, 0, sizeof(ddsd1
));
3565 ddsd1
.dwSize
= sizeof(ddsd1
);
3566 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd1
);
3567 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
3569 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3570 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3571 hr
= set_display_mode(ddraw
, 640, 480);
3572 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3573 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3574 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3576 memset(&ddsd2
, 0, sizeof(ddsd2
));
3577 ddsd2
.dwSize
= sizeof(ddsd2
);
3578 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd2
);
3579 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
3580 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3581 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3583 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
3586 static void test_coop_level_versions(void)
3592 IDirectDrawSurface
*surface
;
3593 IDirectDraw2
*ddraw2
;
3596 window
= CreateWindowA("static", "ddraw_test1", WS_OVERLAPPEDWINDOW
,
3597 0, 0, 640, 480, 0, 0, 0, 0);
3599 ddraw2
= create_ddraw();
3600 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3601 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
3602 restored
= test_mode_restored(ddraw2
, window
);
3603 ok(restored
, "Display mode not restored in new ddraw object\n");
3605 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
3606 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3607 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3609 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3610 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
3611 restored
= test_mode_restored(ddraw2
, window
);
3612 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
3614 /* A successful one does */
3615 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3616 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3617 restored
= test_mode_restored(ddraw2
, window
);
3618 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
3620 IDirectDraw_Release(ddraw
);
3621 IDirectDraw2_Release(ddraw2
);
3623 ddraw2
= create_ddraw();
3624 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3625 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3626 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3628 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
3629 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3630 restored
= test_mode_restored(ddraw2
, window
);
3631 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
3633 IDirectDraw_Release(ddraw
);
3634 IDirectDraw2_Release(ddraw2
);
3636 /* A failing call does not restore the ddraw2+ behavior */
3637 ddraw2
= create_ddraw();
3638 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3639 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3640 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3642 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3643 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3644 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3645 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
3646 restored
= test_mode_restored(ddraw2
, window
);
3647 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
3649 IDirectDraw_Release(ddraw
);
3650 IDirectDraw2_Release(ddraw2
);
3652 /* Neither does a sequence of successful calls with the new interface */
3653 ddraw2
= create_ddraw();
3654 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3655 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3656 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3658 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3659 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3660 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3661 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3662 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
3663 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3665 restored
= test_mode_restored(ddraw2
, window
);
3666 ok(!restored
, "Display mode restored after ddraw1-ddraw2 SetCooperativeLevel() call sequence\n");
3667 IDirectDraw_Release(ddraw
);
3668 IDirectDraw2_Release(ddraw2
);
3670 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
3671 ddraw2
= create_ddraw();
3672 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3673 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3674 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3676 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
3677 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3679 memset(&ddsd
, 0, sizeof(ddsd
));
3680 ddsd
.dwSize
= sizeof(ddsd
);
3681 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
3682 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
3683 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
3684 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3685 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#x.\n", hr
);
3686 IDirectDrawSurface_Release(surface
);
3687 restored
= test_mode_restored(ddraw2
, window
);
3688 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
3690 IDirectDraw_Release(ddraw
);
3691 IDirectDraw2_Release(ddraw2
);
3692 DestroyWindow(window
);
3695 static void test_lighting_interface_versions(void)
3697 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3698 IDirect3DMaterial2
*emissive
, *background
;
3699 IDirect3DViewport2
*viewport
;
3700 IDirect3DDevice2
*device
;
3701 IDirectDrawSurface
*rt
;
3702 IDirectDraw2
*ddraw
;
3706 D3DMATERIALHANDLE mat_handle
;
3710 static D3DVERTEX quad
[] =
3712 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3713 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3714 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3715 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3717 static D3DLVERTEX lquad
[] =
3719 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3720 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3721 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3722 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3724 static D3DTLVERTEX tlquad
[] =
3726 {{ 0.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3727 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3728 {{ 640.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3729 {{ 640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3733 D3DVERTEXTYPE vertextype
;
3735 DWORD d3drs_lighting
, d3drs_specular
;
3741 /* Lighting is enabled when D3DVT_VERTEX is used and D3DDP_DONOTLIGHT is not
3742 * set. D3DVT_VERTEX has diffuse = 0xffffffff and specular = 0x00000000, as
3743 * in later d3d versions */
3744 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, 0, 0x0000ff00},
3745 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, 0, 0x0000ff00},
3746 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3747 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3748 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, 0, 0x0000ff00},
3749 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, 0, 0x0000ff00},
3750 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3751 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3753 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, 0, 0x00ff0000},
3754 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, 0, 0x00ff0000},
3755 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
3756 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
3757 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, 0, 0x00ff8080},
3758 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, 0, 0x00ff8080},
3759 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
3760 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
3762 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, 0, 0x000000ff},
3763 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, 0, 0x000000ff},
3764 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
3765 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
3766 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, 0, 0x008080ff},
3767 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, 0, 0x008080ff},
3768 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
3769 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
3772 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3773 0, 0, 640, 480, 0, 0, 0, 0);
3774 ddraw
= create_ddraw();
3775 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3776 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3778 skip("Failed to create a 3D device, skipping test.\n");
3779 IDirectDraw2_Release(ddraw
);
3780 DestroyWindow(window
);
3784 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
3785 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3787 viewport
= create_viewport(device
, 0, 0, 640, 480);
3788 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
3789 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
3791 emissive
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
3792 hr
= IDirect3DMaterial2_GetHandle(emissive
, device
, &mat_handle
);
3793 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
3794 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
3795 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
3796 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
3797 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#x.\n", hr
);
3799 background
= create_diffuse_material(device
, 0.1f
, 0.1f
, 0.1f
, 0.1f
);
3800 viewport_set_background(device
, viewport
, background
);
3802 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, &rs
);
3803 ok(SUCCEEDED(hr
), "Failed to get specularenable render state, hr %#x.\n", hr
);
3804 ok(rs
== TRUE
, "Initial D3DRENDERSTATE_SPECULARENABLE is %#x, expected TRUE.\n", rs
);
3806 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
3808 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
3809 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3811 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, tests
[i
].d3drs_lighting
);
3812 ok(SUCCEEDED(hr
), "Failed to set lighting render state, hr %#x.\n", hr
);
3813 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
,
3814 tests
[i
].d3drs_specular
);
3815 ok(SUCCEEDED(hr
), "Failed to set specularenable render state, hr %#x.\n", hr
);
3817 hr
= IDirect3DDevice2_BeginScene(device
);
3818 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
3819 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
3820 tests
[i
].vertextype
, tests
[i
].data
, 4, tests
[i
].draw_flags
| D3DDP_WAIT
);
3821 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
3822 hr
= IDirect3DDevice2_EndScene(device
);
3823 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
3825 color
= get_surface_color(rt
, 320, 240);
3826 ok(compare_color(color
, tests
[i
].color
, 1),
3827 "Got unexpected color 0x%08x, expected 0x%08x, test %u.\n",
3828 color
, tests
[i
].color
, i
);
3831 destroy_material(background
);
3832 destroy_material(emissive
);
3833 IDirectDrawSurface_Release(rt
);
3834 IDirect3DDevice2_Release(device
);
3835 ref
= IDirectDraw2_Release(ddraw
);
3836 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
3837 DestroyWindow(window
);
3843 IDirectDraw2
*ddraw
;
3846 } activateapp_testdata
;
3848 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
3850 if (message
== WM_ACTIVATEAPP
)
3852 if (activateapp_testdata
.ddraw
)
3855 activateapp_testdata
.received
= FALSE
;
3856 hr
= IDirectDraw2_SetCooperativeLevel(activateapp_testdata
.ddraw
,
3857 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
3858 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#x.\n", hr
);
3859 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
3861 activateapp_testdata
.received
= TRUE
;
3864 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
3867 static void test_coop_level_activateapp(void)
3869 IDirectDraw2
*ddraw
;
3874 IDirectDrawSurface
*surface
;
3876 ddraw
= create_ddraw();
3877 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3879 wc
.lpfnWndProc
= activateapp_test_proc
;
3880 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
3881 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3883 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
3884 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
3886 /* Exclusive with window already active. */
3887 SetForegroundWindow(window
);
3888 activateapp_testdata
.received
= FALSE
;
3889 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3890 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3891 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
3892 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3893 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3895 /* Exclusive with window not active. */
3896 SetForegroundWindow(GetDesktopWindow());
3897 activateapp_testdata
.received
= FALSE
;
3898 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3899 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3900 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3901 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3902 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3904 /* Normal with window not active, then exclusive with the same window. */
3905 SetForegroundWindow(GetDesktopWindow());
3906 activateapp_testdata
.received
= FALSE
;
3907 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3908 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3909 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
3910 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3911 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3912 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3913 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3914 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3916 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
3917 SetForegroundWindow(GetDesktopWindow());
3918 activateapp_testdata
.received
= FALSE
;
3919 activateapp_testdata
.ddraw
= ddraw
;
3920 activateapp_testdata
.window
= window
;
3921 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
3922 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3923 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3924 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3925 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3926 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3928 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
3929 * succeeding. Another switch to exclusive and back to normal is needed to release the
3930 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
3931 * WM_ACTIVATEAPP messages. */
3932 activateapp_testdata
.ddraw
= NULL
;
3933 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3934 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3935 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3936 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3938 /* Setting DDSCL_NORMAL with recursive invocation. */
3939 SetForegroundWindow(GetDesktopWindow());
3940 activateapp_testdata
.received
= FALSE
;
3941 activateapp_testdata
.ddraw
= ddraw
;
3942 activateapp_testdata
.window
= window
;
3943 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
3944 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3945 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3946 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3948 /* DDraw is in exlusive mode now. */
3949 memset(&ddsd
, 0, sizeof(ddsd
));
3950 ddsd
.dwSize
= sizeof(ddsd
);
3951 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
3952 ddsd
.dwBackBufferCount
= 1;
3953 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
3954 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3955 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
3956 IDirectDrawSurface_Release(surface
);
3958 /* Recover again, just to be sure. */
3959 activateapp_testdata
.ddraw
= NULL
;
3960 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3961 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3962 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3963 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3965 DestroyWindow(window
);
3966 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3967 IDirectDraw2_Release(ddraw
);
3970 struct format_support_check
3972 const DDPIXELFORMAT
*format
;
3976 static HRESULT WINAPI
test_unsupported_formats_cb(DDSURFACEDESC
*desc
, void *ctx
)
3978 struct format_support_check
*format
= ctx
;
3980 if (!memcmp(format
->format
, &desc
->ddpfPixelFormat
, sizeof(*format
->format
)))
3982 format
->supported
= TRUE
;
3983 return DDENUMRET_CANCEL
;
3986 return DDENUMRET_OK
;
3989 static void test_unsupported_formats(void)
3992 BOOL expect_success
;
3994 IDirectDraw2
*ddraw
;
3995 IDirect3DDevice2
*device
;
3996 IDirectDrawSurface
*surface
;
3999 DWORD expected_caps
;
4010 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
4011 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
4017 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
4018 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
4022 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
4024 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4025 0, 0, 640, 480, 0, 0, 0, 0);
4026 ddraw
= create_ddraw();
4027 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4028 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4030 skip("Failed to create a 3D device, skipping test.\n");
4031 IDirectDraw2_Release(ddraw
);
4032 DestroyWindow(window
);
4036 for (i
= 0; i
< sizeof(formats
) / sizeof(*formats
); i
++)
4038 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
4039 hr
= IDirect3DDevice2_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
4040 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
4042 for (j
= 0; j
< sizeof(caps
) / sizeof(*caps
); j
++)
4044 memset(&ddsd
, 0, sizeof(ddsd
));
4045 ddsd
.dwSize
= sizeof(ddsd
);
4046 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
4047 ddsd
.ddpfPixelFormat
= formats
[i
].fmt
;
4050 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
4052 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
4053 expect_success
= FALSE
;
4055 expect_success
= TRUE
;
4057 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4058 ok(SUCCEEDED(hr
) == expect_success
,
4059 "Got unexpected hr %#x for format %s, caps %#x, expected %s.\n",
4060 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
4064 memset(&ddsd
, 0, sizeof(ddsd
));
4065 ddsd
.dwSize
= sizeof(ddsd
);
4066 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &ddsd
);
4067 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4069 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
4070 expected_caps
= DDSCAPS_VIDEOMEMORY
;
4071 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
4072 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
4073 else if (check
.supported
)
4074 expected_caps
= DDSCAPS_VIDEOMEMORY
;
4076 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
4078 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
4079 "Expected capability %#x, format %s, input cap %#x.\n",
4080 expected_caps
, formats
[i
].name
, caps
[j
]);
4082 IDirectDrawSurface_Release(surface
);
4086 IDirect3DDevice2_Release(device
);
4087 IDirectDraw2_Release(ddraw
);
4088 DestroyWindow(window
);
4091 static void test_rt_caps(void)
4093 PALETTEENTRY palette_entries
[256];
4094 IDirectDrawPalette
*palette
;
4095 IDirect3DDevice2
*device
;
4096 IDirectDraw2
*ddraw
;
4104 static const DDPIXELFORMAT p8_fmt
=
4106 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
4107 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
4112 const DDPIXELFORMAT
*pf
;
4115 HRESULT create_device_hr
;
4117 HRESULT alternative_set_rt_hr
;
4118 BOOL create_may_fail
;
4124 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
4125 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4133 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4134 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4142 DDSCAPS_OFFSCREENPLAIN
,
4143 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4151 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4152 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4153 D3DERR_SURFACENOTINVIDMEM
,
4160 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4161 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4169 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
4170 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4179 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4188 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4196 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4197 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4198 D3DERR_SURFACENOTINVIDMEM
,
4205 DDSCAPS_SYSTEMMEMORY
,
4206 DDSCAPS_SYSTEMMEMORY
,
4215 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4223 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4225 DDERR_NOPALETTEATTACHED
,
4232 DDSCAPS_OFFSCREENPLAIN
,
4233 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4241 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4242 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4243 DDERR_NOPALETTEATTACHED
,
4250 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4251 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4259 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
4260 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
4262 DDERR_INVALIDPIXELFORMAT
,
4264 TRUE
/* AMD Evergreen */,
4268 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
4269 ~0U /* AMD Evergreen */,
4271 DDERR_INVALIDPIXELFORMAT
,
4278 ~0U /* AMD Evergreen */,
4286 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
4287 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
4289 DDERR_INVALIDPIXELFORMAT
,
4290 DDERR_INVALIDPIXELFORMAT
,
4291 TRUE
/* Nvidia Kepler */,
4295 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
4296 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
4300 TRUE
/* Nvidia Kepler */,
4304 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4305 0, 0, 640, 480, 0, 0, 0, 0);
4306 ddraw
= create_ddraw();
4307 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4308 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4310 skip("Failed to create a 3D device, skipping test.\n");
4311 IDirectDraw2_Release(ddraw
);
4312 DestroyWindow(window
);
4315 z_depth
= get_device_z_depth(device
);
4316 ok(!!z_depth
, "Failed to get device z depth.\n");
4317 IDirect3DDevice2_Release(device
);
4319 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
4321 skip("D3D interface is not available, skipping test.\n");
4325 memset(palette_entries
, 0, sizeof(palette_entries
));
4326 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
4327 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
4329 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
4331 IDirectDrawSurface
*surface
, *rt
, *expected_rt
, *tmp
;
4332 DDSURFACEDESC surface_desc
;
4333 IDirect3DDevice2
*device
;
4335 memset(&surface_desc
, 0, sizeof(surface_desc
));
4336 surface_desc
.dwSize
= sizeof(surface_desc
);
4337 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4338 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
4339 if (test_data
[i
].pf
)
4341 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
4342 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
4344 if (test_data
[i
].caps_in
& DDSCAPS_ZBUFFER
)
4346 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4347 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
4349 surface_desc
.dwWidth
= 640;
4350 surface_desc
.dwHeight
= 480;
4351 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4352 ok(SUCCEEDED(hr
) || broken(test_data
[i
].create_may_fail
),
4353 "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
4354 i
, test_data
[i
].caps_in
, hr
);
4358 memset(&surface_desc
, 0, sizeof(surface_desc
));
4359 surface_desc
.dwSize
= sizeof(surface_desc
);
4360 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
4361 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
4362 ok(test_data
[i
].caps_out
== ~0U || surface_desc
.ddsCaps
.dwCaps
== test_data
[i
].caps_out
,
4363 "Test %u: Got unexpected caps %#x, expected %#x.\n",
4364 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
4366 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
4367 ok(hr
== test_data
[i
].create_device_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n",
4368 i
, hr
, test_data
[i
].create_device_hr
);
4371 if (hr
== DDERR_NOPALETTEATTACHED
)
4373 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
4374 ok(SUCCEEDED(hr
), "Test %u: Failed to set palette, hr %#x.\n", i
, hr
);
4375 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
4376 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
4377 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
4379 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
4381 IDirectDrawSurface_Release(surface
);
4383 memset(&surface_desc
, 0, sizeof(surface_desc
));
4384 surface_desc
.dwSize
= sizeof(surface_desc
);
4385 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4386 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
4387 surface_desc
.dwWidth
= 640;
4388 surface_desc
.dwHeight
= 480;
4389 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4390 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface, hr %#x.\n", i
, hr
);
4392 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
4393 ok(SUCCEEDED(hr
), "Test %u: Failed to create device, hr %#x.\n", i
, hr
);
4396 memset(&surface_desc
, 0, sizeof(surface_desc
));
4397 surface_desc
.dwSize
= sizeof(surface_desc
);
4398 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4399 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
4400 if (test_data
[i
].pf
)
4402 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
4403 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
4405 if (test_data
[i
].caps_in
& DDSCAPS_ZBUFFER
)
4407 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4408 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
4410 surface_desc
.dwWidth
= 640;
4411 surface_desc
.dwHeight
= 480;
4412 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
4413 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
4414 i
, test_data
[i
].caps_in
, hr
);
4416 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
4417 ok(hr
== test_data
[i
].set_rt_hr
|| broken(hr
== test_data
[i
].alternative_set_rt_hr
),
4418 "Test %u: Got unexpected hr %#x, expected %#x.\n",
4419 i
, hr
, test_data
[i
].set_rt_hr
);
4420 if (SUCCEEDED(hr
) || hr
== DDERR_INVALIDPIXELFORMAT
)
4423 expected_rt
= surface
;
4425 /* It appears the surface is set as render target in this case, but no
4426 * reference is taken. */
4427 if (hr
== DDERR_INVALIDPIXELFORMAT
)
4429 refcount
= IDirectDrawSurface_AddRef(rt
);
4430 ok(refcount
== 2, "Test %u: Got unexpected refcount %u.\n", i
, refcount
);
4433 hr
= IDirect3DDevice2_GetRenderTarget(device
, &tmp
);
4434 ok(SUCCEEDED(hr
), "Test %u: Failed to get render target, hr %#x.\n", i
, hr
);
4435 ok(tmp
== expected_rt
, "Test %u: Got unexpected rt %p.\n", i
, tmp
);
4437 IDirectDrawSurface_Release(tmp
);
4438 IDirectDrawSurface_Release(rt
);
4439 refcount
= IDirect3DDevice2_Release(device
);
4440 ok(refcount
== 0, "Test %u: The device was not properly freed, refcount %u.\n", i
, refcount
);
4441 refcount
= IDirectDrawSurface_Release(surface
);
4442 ok(refcount
== 0, "Test %u: The surface was not properly freed, refcount %u.\n", i
, refcount
);
4445 IDirectDrawPalette_Release(palette
);
4446 IDirect3D2_Release(d3d
);
4449 refcount
= IDirectDraw2_Release(ddraw
);
4450 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4451 DestroyWindow(window
);
4454 static void test_primary_caps(void)
4456 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
4457 IDirectDrawSurface
*surface
;
4458 DDSURFACEDESC surface_desc
;
4459 IDirectDraw2
*ddraw
;
4469 DWORD back_buffer_count
;
4477 DDSCAPS_PRIMARYSURFACE
,
4480 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
4484 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
4491 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
4498 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
4505 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
4512 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
4519 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4526 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4533 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4535 DDERR_NOEXCLUSIVEMODE
,
4539 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4540 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4546 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4547 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4550 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
4553 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4554 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
4560 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4561 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
4568 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4569 0, 0, 640, 480, 0, 0, 0, 0);
4570 ddraw
= create_ddraw();
4571 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4573 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
4575 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
4576 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4578 memset(&surface_desc
, 0, sizeof(surface_desc
));
4579 surface_desc
.dwSize
= sizeof(surface_desc
);
4580 surface_desc
.dwFlags
= DDSD_CAPS
;
4581 if (test_data
[i
].back_buffer_count
!= ~0u)
4582 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
4583 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
4584 surface_desc
.dwBackBufferCount
= test_data
[i
].back_buffer_count
;
4585 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4586 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
4590 memset(&surface_desc
, 0, sizeof(surface_desc
));
4591 surface_desc
.dwSize
= sizeof(surface_desc
);
4592 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
4593 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
4594 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
4595 "Test %u: Got unexpected caps %#x, expected %#x.\n",
4596 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
4598 IDirectDrawSurface_Release(surface
);
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 test_surface_lock(void)
4608 IDirectDraw2
*ddraw
;
4609 IDirectDrawSurface
*surface
;
4610 IDirect3DDevice2
*device
;
4625 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
4626 "videomemory offscreenplain"
4629 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4630 "systemmemory offscreenplain"
4633 DDSCAPS_PRIMARYSURFACE
,
4637 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
4638 "videomemory texture"
4641 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
4642 "systemmemory texture"
4645 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4654 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4655 0, 0, 640, 480, 0, 0, 0, 0);
4656 ddraw
= create_ddraw();
4657 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4658 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4660 skip("Failed to create a 3D device, skipping test.\n");
4661 IDirectDraw2_Release(ddraw
);
4662 DestroyWindow(window
);
4665 z_depth
= get_device_z_depth(device
);
4666 ok(!!z_depth
, "Failed to get device z depth.\n");
4667 IDirect3DDevice2_Release(device
);
4669 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
4671 memset(&ddsd
, 0, sizeof(ddsd
));
4672 ddsd
.dwSize
= sizeof(ddsd
);
4673 ddsd
.dwFlags
= DDSD_CAPS
;
4674 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
4676 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
4680 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
4682 ddsd
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4683 U2(ddsd
).dwZBufferBitDepth
= z_depth
;
4685 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
4687 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4688 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4690 memset(&ddsd
, 0, sizeof(ddsd
));
4691 ddsd
.dwSize
= sizeof(ddsd
);
4692 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
4693 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4696 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4697 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4700 IDirectDrawSurface_Release(surface
);
4703 refcount
= IDirectDraw2_Release(ddraw
);
4704 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4705 DestroyWindow(window
);
4708 static void test_surface_discard(void)
4710 IDirectDraw2
*ddraw
;
4711 IDirect3DDevice2
*device
;
4715 IDirectDrawSurface
*surface
, *target
;
4724 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, TRUE
},
4725 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
4726 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, TRUE
},
4727 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
4731 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4732 0, 0, 640, 480, 0, 0, 0, 0);
4733 ddraw
= create_ddraw();
4734 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4735 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4737 skip("Failed to create a 3D device, skipping test.\n");
4738 DestroyWindow(window
);
4739 IDirectDraw2_Release(ddraw
);
4743 hr
= IDirect3DDevice2_GetRenderTarget(device
, &target
);
4744 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4746 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
4750 memset(&ddsd
, 0, sizeof(ddsd
));
4751 ddsd
.dwSize
= sizeof(ddsd
);
4752 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4753 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
4756 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4759 skip("Failed to create surface, skipping.\n");
4763 memset(&ddsd
, 0, sizeof(ddsd
));
4764 ddsd
.dwSize
= sizeof(ddsd
);
4765 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
4766 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4767 addr
= ddsd
.lpSurface
;
4768 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4769 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4771 memset(&ddsd
, 0, sizeof(ddsd
));
4772 ddsd
.dwSize
= sizeof(ddsd
);
4773 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
4774 ok(SUCCEEDED(hr
) , "Failed to lock surface, hr %#x.\n", hr
);
4775 discarded
= ddsd
.lpSurface
!= addr
;
4776 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4777 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4779 hr
= IDirectDrawSurface_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
4780 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
4782 memset(&ddsd
, 0, sizeof(ddsd
));
4783 ddsd
.dwSize
= sizeof(ddsd
);
4784 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
4785 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4786 discarded
|= ddsd
.lpSurface
!= addr
;
4787 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4788 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4790 IDirectDrawSurface_Release(surface
);
4792 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
4793 * AMD r500, evergreen). Windows XP, at least on AMD r200, never changes the pointer. */
4794 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
4797 IDirectDrawSurface_Release(target
);
4798 IDirect3DDevice2_Release(device
);
4799 IDirectDraw2_Release(ddraw
);
4800 DestroyWindow(window
);
4803 static void test_flip(void)
4805 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
4806 IDirectDrawSurface
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
4807 DDSCAPS caps
= {DDSCAPS_FLIP
};
4808 DDSURFACEDESC surface_desc
;
4809 BOOL sysmem_primary
;
4810 IDirectDraw2
*ddraw
;
4811 DWORD expected_caps
;
4826 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
4827 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
4828 {"TEXTURE", DDSCAPS_TEXTURE
},
4831 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4832 0, 0, 640, 480, 0, 0, 0, 0);
4833 ddraw
= create_ddraw();
4834 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4836 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4837 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4839 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
4841 memset(&surface_desc
, 0, sizeof(surface_desc
));
4842 surface_desc
.dwSize
= sizeof(surface_desc
);
4843 surface_desc
.dwFlags
= DDSD_CAPS
;
4844 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
4845 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
4846 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
4847 surface_desc
.dwWidth
= 512;
4848 surface_desc
.dwHeight
= 512;
4849 surface_desc
.dwBackBufferCount
= 3;
4850 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
4851 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4853 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
4854 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
4855 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
4856 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4858 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
4859 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
4860 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
4861 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4863 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
4864 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
4865 todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
4866 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
4870 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
4871 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
4872 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
4873 ok(hr
== DD_OK
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4874 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
4875 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
4876 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4878 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
4879 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4880 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
4881 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
4882 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4883 hr
= restore_surfaces(ddraw
);
4884 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#x.\n", test_data
[i
].name
, hr
);
4886 memset(&surface_desc
, 0, sizeof(surface_desc
));
4887 surface_desc
.dwSize
= sizeof(surface_desc
);
4888 hr
= IDirectDrawSurface_GetSurfaceDesc(frontbuffer
, &surface_desc
);
4889 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
4890 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
4891 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
4892 expected_caps
|= DDSCAPS_VISIBLE
;
4893 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
4894 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
4895 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
4897 hr
= IDirectDrawSurface_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
4898 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
4899 memset(&surface_desc
, 0, sizeof(surface_desc
));
4900 surface_desc
.dwSize
= sizeof(surface_desc
);
4901 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer1
, &surface_desc
);
4902 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
4903 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
4904 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
4905 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
4906 expected_caps
|= DDSCAPS_BACKBUFFER
;
4907 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
4908 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
4910 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
4911 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
4912 memset(&surface_desc
, 0, sizeof(surface_desc
));
4913 surface_desc
.dwSize
= sizeof(surface_desc
);
4914 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer2
, &surface_desc
);
4915 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
4916 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
4917 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
4918 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
4919 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
4920 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
4922 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
4923 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
4924 memset(&surface_desc
, 0, sizeof(surface_desc
));
4925 surface_desc
.dwSize
= sizeof(surface_desc
);
4926 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer3
, &surface_desc
);
4927 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
4928 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
4929 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
4930 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
4931 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
4933 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
4934 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
4935 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
4936 test_data
[i
].name
, surface
, frontbuffer
);
4937 IDirectDrawSurface_Release(surface
);
4939 memset(&surface_desc
, 0, sizeof(surface_desc
));
4940 surface_desc
.dwSize
= sizeof(surface_desc
);
4941 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4942 surface_desc
.ddsCaps
.dwCaps
= 0;
4943 surface_desc
.dwWidth
= 640;
4944 surface_desc
.dwHeight
= 480;
4945 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4946 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
4947 hr
= IDirectDrawSurface_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
4948 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4949 IDirectDrawSurface_Release(surface
);
4951 hr
= IDirectDrawSurface_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
4952 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4953 hr
= IDirectDrawSurface_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
4954 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4955 hr
= IDirectDrawSurface_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
4956 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4957 hr
= IDirectDrawSurface_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
4958 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4960 memset(&fx
, 0, sizeof(fx
));
4961 fx
.dwSize
= sizeof(fx
);
4962 U5(fx
).dwFillColor
= 0xffff0000;
4963 hr
= IDirectDrawSurface_Blt(backbuffer1
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4964 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
4965 U5(fx
).dwFillColor
= 0xff00ff00;
4966 hr
= IDirectDrawSurface_Blt(backbuffer2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4967 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
4968 U5(fx
).dwFillColor
= 0xff0000ff;
4969 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4970 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
4972 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
4973 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
4974 color
= get_surface_color(backbuffer1
, 320, 240);
4975 /* The testbot seems to just copy the contents of one surface to all the
4976 * others, instead of properly flipping. */
4977 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
4978 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4979 color
= get_surface_color(backbuffer2
, 320, 240);
4980 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4981 U5(fx
).dwFillColor
= 0xffff0000;
4982 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4983 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
4985 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
4986 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
4987 color
= get_surface_color(backbuffer1
, 320, 240);
4988 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
4989 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4990 color
= get_surface_color(backbuffer2
, 320, 240);
4991 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4992 U5(fx
).dwFillColor
= 0xff00ff00;
4993 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4994 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
4996 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
4997 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
4998 color
= get_surface_color(backbuffer1
, 320, 240);
4999 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
5000 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5001 color
= get_surface_color(backbuffer2
, 320, 240);
5002 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5003 U5(fx
).dwFillColor
= 0xff0000ff;
5004 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
5005 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
5007 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
5008 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5009 color
= get_surface_color(backbuffer2
, 320, 240);
5010 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
5011 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5012 color
= get_surface_color(backbuffer3
, 320, 240);
5013 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5014 U5(fx
).dwFillColor
= 0xffff0000;
5015 hr
= IDirectDrawSurface_Blt(backbuffer1
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
5016 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
5018 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
5019 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5020 color
= get_surface_color(backbuffer1
, 320, 240);
5021 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5022 color
= get_surface_color(backbuffer3
, 320, 240);
5023 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
5024 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5025 U5(fx
).dwFillColor
= 0xff00ff00;
5026 hr
= IDirectDrawSurface_Blt(backbuffer2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
5027 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
5029 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
5030 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5031 color
= get_surface_color(backbuffer1
, 320, 240);
5032 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
5033 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5034 color
= get_surface_color(backbuffer2
, 320, 240);
5035 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5037 IDirectDrawSurface_Release(backbuffer3
);
5038 IDirectDrawSurface_Release(backbuffer2
);
5039 IDirectDrawSurface_Release(backbuffer1
);
5040 IDirectDrawSurface_Release(frontbuffer
);
5043 refcount
= IDirectDraw2_Release(ddraw
);
5044 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
5045 DestroyWindow(window
);
5048 static void reset_ddsd(DDSURFACEDESC
*ddsd
)
5050 memset(ddsd
, 0, sizeof(*ddsd
));
5051 ddsd
->dwSize
= sizeof(*ddsd
);
5054 static void test_set_surface_desc(void)
5056 IDirectDraw2
*ddraw
;
5060 IDirectDrawSurface
*surface
;
5061 IDirectDrawSurface3
*surface3
;
5071 invalid_caps_tests
[] =
5073 {DDSCAPS_VIDEOMEMORY
, FALSE
, "videomemory plain"},
5074 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, TRUE
, "systemmemory texture"},
5075 {DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
, FALSE
, "systemmemory primary"},
5078 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5079 0, 0, 640, 480, 0, 0, 0, 0);
5080 ddraw
= create_ddraw();
5081 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5082 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5083 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5086 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
5089 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5090 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5091 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5092 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5093 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5094 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5095 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5097 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5098 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5100 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
5101 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
5102 IDirectDrawSurface_Release(surface
);
5105 ddsd
.dwFlags
= DDSD_LPSURFACE
;
5106 ddsd
.lpSurface
= data
;
5107 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5108 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5110 /* Redundantly setting the same lpSurface is not an error. */
5111 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5112 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5113 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5114 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5115 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
5116 ok(ddsd
.lpSurface
== NULL
, "lpSurface is %p, expected NULL.\n", ddsd
.lpSurface
);
5118 hr
= IDirectDrawSurface3_Lock(surface3
, NULL
, &ddsd
, 0, NULL
);
5119 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
5120 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
5121 ok(ddsd
.lpSurface
== data
, "lpSurface is %p, expected %p.\n", data
, data
);
5122 hr
= IDirectDrawSurface3_Unlock(surface3
, NULL
);
5123 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5126 ddsd
.dwFlags
= DDSD_LPSURFACE
;
5127 ddsd
.lpSurface
= data
;
5128 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 1);
5129 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with flags=1 returned %#x.\n", hr
);
5131 ddsd
.lpSurface
= NULL
;
5132 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5133 ok(hr
== DDERR_INVALIDPARAMS
, "Setting lpSurface=NULL returned %#x.\n", hr
);
5135 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, NULL
, 0);
5136 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with NULL desc returned %#x.\n", hr
);
5138 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5139 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5140 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
5141 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
5143 /* Setting the caps is an error. This also means the original description cannot be reapplied. */
5144 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5145 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the original desc returned %#x.\n", hr
);
5147 ddsd
.dwFlags
= DDSD_CAPS
;
5148 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5149 ok(hr
== DDERR_INVALIDPARAMS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
5151 /* dwCaps = 0 is allowed, but ignored. */
5152 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_LPSURFACE
;
5153 ddsd
.lpSurface
= data
;
5154 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5155 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
5156 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5157 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5158 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
5159 ddsd
.ddsCaps
.dwCaps
= 0;
5160 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5161 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5163 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5164 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5165 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
5166 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
5168 /* Setting the height is allowed, but it cannot be set to 0, and only if LPSURFACE is set too. */
5170 ddsd
.dwFlags
= DDSD_HEIGHT
;
5172 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5173 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height without lpSurface returned %#x.\n", hr
);
5175 ddsd
.lpSurface
= data
;
5176 ddsd
.dwFlags
= DDSD_HEIGHT
| DDSD_LPSURFACE
;
5177 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5178 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5181 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5182 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height=0 returned %#x.\n", hr
);
5185 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5186 ok(SUCCEEDED(hr
), "GetSurfaceDesc failed, hr %#x.\n", hr
);
5187 ok(ddsd
.dwWidth
== 8, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
5188 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
5190 /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0. */
5192 ddsd
.dwFlags
= DDSD_PITCH
;
5193 U1(ddsd
).lPitch
= 8 * 4;
5194 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5195 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch without lpSurface or width returned %#x.\n", hr
);
5197 ddsd
.dwFlags
= DDSD_WIDTH
;
5199 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5200 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width without lpSurface or pitch returned %#x.\n", hr
);
5202 ddsd
.dwFlags
= DDSD_PITCH
| DDSD_LPSURFACE
;
5203 ddsd
.lpSurface
= data
;
5204 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5205 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch and lpSurface without width returned %#x.\n", hr
);
5207 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_LPSURFACE
;
5208 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5209 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width and lpSurface without pitch returned %#x.\n", hr
);
5211 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
5212 U1(ddsd
).lPitch
= 16 * 4;
5214 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5215 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5218 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5219 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5220 ok(ddsd
.dwWidth
== 16, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
5221 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
5222 ok(U1(ddsd
).lPitch
== 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %u.\n", U1(ddsd
).lPitch
);
5224 /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise.
5226 * VMware rejects those calls, but all real drivers accept it. Mark the VMware behavior broken. */
5227 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
5228 U1(ddsd
).lPitch
= 4 * 4;
5229 ddsd
.lpSurface
= data
;
5230 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5231 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
5233 U1(ddsd
).lPitch
= 4;
5234 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5235 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
5237 U1(ddsd
).lPitch
= 16 * 4 + 1;
5238 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5239 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
5241 U1(ddsd
).lPitch
= 16 * 4 + 3;
5242 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5243 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
5245 U1(ddsd
).lPitch
= -4;
5246 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5247 ok(hr
== DDERR_INVALIDPARAMS
, "Setting negative pitch returned %#x.\n", hr
);
5249 U1(ddsd
).lPitch
= 16 * 4;
5250 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5251 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5254 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
5255 U1(ddsd
).lPitch
= 0;
5257 ddsd
.lpSurface
= data
;
5258 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5259 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero pitch returned %#x.\n", hr
);
5261 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
5262 U1(ddsd
).lPitch
= 16 * 4;
5264 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5265 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero width returned %#x.\n", hr
);
5267 /* Setting the pixelformat without LPSURFACE is an error, but with LPSURFACE it works. */
5268 ddsd
.dwFlags
= DDSD_PIXELFORMAT
;
5269 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5270 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5271 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5272 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5273 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5274 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5275 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5276 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the pixel format returned %#x.\n", hr
);
5278 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
5279 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5280 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5282 /* Can't set color keys. */
5284 ddsd
.dwFlags
= DDSD_CKSRCBLT
;
5285 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff0000;
5286 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff0000;
5287 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5288 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
5290 ddsd
.dwFlags
= DDSD_CKSRCBLT
| DDSD_LPSURFACE
;
5291 ddsd
.lpSurface
= data
;
5292 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5293 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
5295 IDirectDrawSurface3_Release(surface3
);
5297 /* SetSurfaceDesc needs systemmemory surfaces.
5299 * As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing DDSD_LINEARSIZE is moot. */
5300 for (i
= 0; i
< sizeof(invalid_caps_tests
) / sizeof(*invalid_caps_tests
); i
++)
5303 ddsd
.dwFlags
= DDSD_CAPS
;
5304 ddsd
.ddsCaps
.dwCaps
= invalid_caps_tests
[i
].caps
;
5305 if (!(invalid_caps_tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
5307 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5310 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5311 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5312 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5313 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5314 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5315 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5318 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5319 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
, "Failed to create surface, hr %#x.\n", hr
);
5322 skip("Cannot create a %s surface, skipping vidmem SetSurfaceDesc test.\n",
5323 invalid_caps_tests
[i
].name
);
5326 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
5327 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
5328 IDirectDrawSurface_Release(surface
);
5331 ddsd
.dwFlags
= DDSD_LPSURFACE
;
5332 ddsd
.lpSurface
= data
;
5333 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5334 if (invalid_caps_tests
[i
].supported
)
5336 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5340 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
5341 invalid_caps_tests
[i
].name
, hr
);
5343 /* Check priority of error conditions. */
5344 ddsd
.dwFlags
= DDSD_WIDTH
;
5345 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5346 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
5347 invalid_caps_tests
[i
].name
, hr
);
5350 IDirectDrawSurface3_Release(surface3
);
5354 ref
= IDirectDraw2_Release(ddraw
);
5355 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
5356 DestroyWindow(window
);
5359 static void test_user_memory_getdc(void)
5361 IDirectDraw2
*ddraw
;
5365 IDirectDrawSurface
*surface
;
5366 IDirectDrawSurface3
*surface3
;
5375 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5376 0, 0, 640, 480, 0, 0, 0, 0);
5377 ddraw
= create_ddraw();
5378 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5380 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5381 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5384 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
5387 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5388 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5389 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5390 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5391 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5392 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5393 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5394 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5395 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5397 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
5398 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
5399 IDirectDrawSurface_Release(surface
);
5401 memset(data
, 0xaa, sizeof(data
));
5403 ddsd
.dwFlags
= DDSD_LPSURFACE
;
5404 ddsd
.lpSurface
= data
;
5405 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5406 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5408 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
5409 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
5410 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
5411 ok(!!bitmap
, "Failed to get bitmap.\n");
5412 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
5413 ok(size
== sizeof(dib
), "Got unexpected size %d.\n", size
);
5414 ok(dib
.dsBm
.bmBits
== data
, "Got unexpected bits %p, expected %p.\n", dib
.dsBm
.bmBits
, data
);
5415 BitBlt(dc
, 0, 0, 16, 8, NULL
, 0, 0, WHITENESS
);
5416 BitBlt(dc
, 0, 8, 16, 8, NULL
, 0, 0, BLACKNESS
);
5417 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
5418 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
5420 ok(data
[0][0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data
[0][0]);
5421 ok(data
[15][15] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data
[15][15]);
5423 ddsd
.dwFlags
= DDSD_LPSURFACE
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
;
5424 ddsd
.lpSurface
= data
;
5427 U1(ddsd
).lPitch
= sizeof(*data
);
5428 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5429 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5431 memset(data
, 0xaa, sizeof(data
));
5432 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
5433 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
5434 BitBlt(dc
, 0, 0, 4, 8, NULL
, 0, 0, BLACKNESS
);
5435 BitBlt(dc
, 1, 1, 2, 2, NULL
, 0, 0, WHITENESS
);
5436 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
5437 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
5439 for (y
= 0; y
< 4; y
++)
5441 for (x
= 0; x
< 4; x
++)
5443 if ((x
== 1 || x
== 2) && (y
== 1 || y
== 2))
5444 ok(data
[y
][x
] == 0xffffffff, "Expected color 0xffffffff on position %ux%u, got %#x.\n",
5447 ok(data
[y
][x
] == 0x00000000, "Expected color 0xaaaaaaaa on position %ux%u, got %#x.\n",
5451 ok(data
[0][5] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 5x0, got %#x.\n",
5453 ok(data
[7][3] == 0x00000000, "Expected color 0x00000000 on position 3x7, got %#x.\n",
5455 ok(data
[7][4] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 4x7, got %#x.\n",
5457 ok(data
[8][0] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 0x8, got %#x.\n",
5460 IDirectDrawSurface3_Release(surface3
);
5461 ref
= IDirectDraw2_Release(ddraw
);
5462 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
5463 DestroyWindow(window
);
5466 static void test_sysmem_overlay(void)
5468 IDirectDraw2
*ddraw
;
5472 IDirectDrawSurface
*surface
;
5475 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5476 0, 0, 640, 480, 0, 0, 0, 0);
5477 ddraw
= create_ddraw();
5478 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5480 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5481 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5484 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
5487 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
5488 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5489 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5490 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5491 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5492 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5493 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5494 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5495 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#x.\n", hr
);
5497 ref
= IDirectDraw2_Release(ddraw
);
5498 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
5499 DestroyWindow(window
);
5502 static void test_primary_palette(void)
5504 DDSCAPS surface_caps
= {DDSCAPS_FLIP
};
5505 IDirectDrawSurface
*primary
, *backbuffer
;
5506 PALETTEENTRY palette_entries
[256];
5507 IDirectDrawPalette
*palette
, *tmp
;
5508 DDSURFACEDESC surface_desc
;
5509 IDirectDraw2
*ddraw
;
5515 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5516 0, 0, 640, 480, 0, 0, 0, 0);
5517 ddraw
= create_ddraw();
5518 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5519 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
5521 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
5522 IDirectDraw2_Release(ddraw
);
5523 DestroyWindow(window
);
5526 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5527 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5529 memset(&surface_desc
, 0, sizeof(surface_desc
));
5530 surface_desc
.dwSize
= sizeof(surface_desc
);
5531 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
5532 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
5533 surface_desc
.dwBackBufferCount
= 1;
5534 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
5535 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5536 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
5537 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
5539 memset(palette_entries
, 0, sizeof(palette_entries
));
5540 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
5541 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
5542 refcount
= get_refcount((IUnknown
*)palette
);
5543 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5545 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5546 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
5547 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
5549 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
5550 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5552 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
5553 * and is generally somewhat broken with respect to 8 bpp / palette
5555 if (SUCCEEDED(IDirectDrawSurface_GetPalette(backbuffer
, &tmp
)))
5557 win_skip("Broken palette handling detected, skipping tests.\n");
5558 IDirectDrawPalette_Release(tmp
);
5559 IDirectDrawPalette_Release(palette
);
5560 /* The Windows 8 testbot keeps extra references to the primary and
5561 * backbuffer while in 8 bpp mode. */
5562 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
5563 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
5567 refcount
= get_refcount((IUnknown
*)palette
);
5568 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5570 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5571 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
5572 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
5573 "Got unexpected palette caps %#x.\n", palette_caps
);
5575 hr
= IDirectDrawSurface_SetPalette(primary
, NULL
);
5576 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5577 refcount
= get_refcount((IUnknown
*)palette
);
5578 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5580 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5581 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
5582 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
5584 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
5585 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5586 refcount
= get_refcount((IUnknown
*)palette
);
5587 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5589 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
5590 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
5591 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
5592 IDirectDrawPalette_Release(tmp
);
5593 hr
= IDirectDrawSurface_GetPalette(backbuffer
, &tmp
);
5594 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
5596 refcount
= IDirectDrawPalette_Release(palette
);
5597 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5598 refcount
= IDirectDrawPalette_Release(palette
);
5599 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5601 /* Note that this only seems to work when the palette is attached to the
5602 * primary surface. When attached to a regular surface, attempting to get
5603 * the palette here will cause an access violation. */
5604 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
5605 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
5608 refcount
= IDirectDrawSurface_Release(backbuffer
);
5609 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5610 refcount
= IDirectDrawSurface_Release(primary
);
5611 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5612 refcount
= IDirectDraw2_Release(ddraw
);
5613 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5614 DestroyWindow(window
);
5617 static HRESULT WINAPI
surface_counter(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
5619 UINT
*surface_count
= context
;
5622 IDirectDrawSurface_Release(surface
);
5624 return DDENUMRET_OK
;
5627 static void test_surface_attachment(void)
5629 IDirectDrawSurface
*surface1
, *surface2
, *surface3
, *surface4
;
5630 DDSCAPS caps
= {DDSCAPS_TEXTURE
};
5631 DDSURFACEDESC surface_desc
;
5632 IDirectDraw2
*ddraw
;
5638 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5639 0, 0, 640, 480, 0, 0, 0, 0);
5640 ddraw
= create_ddraw();
5641 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5642 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5643 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5645 memset(&surface_desc
, 0, sizeof(surface_desc
));
5646 surface_desc
.dwSize
= sizeof(surface_desc
);
5647 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
5648 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
5649 U2(surface_desc
).dwMipMapCount
= 3;
5650 surface_desc
.dwWidth
= 128;
5651 surface_desc
.dwHeight
= 128;
5652 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5653 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5655 hr
= IDirectDrawSurface_GetAttachedSurface(surface1
, &caps
, &surface2
);
5656 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
5657 hr
= IDirectDrawSurface_GetAttachedSurface(surface2
, &caps
, &surface3
);
5658 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
5659 hr
= IDirectDrawSurface_GetAttachedSurface(surface3
, &caps
, &surface4
);
5660 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
5663 IDirectDrawSurface_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
5664 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
5666 IDirectDrawSurface_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
5667 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
5669 IDirectDrawSurface_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
5670 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
5672 memset(&surface_desc
, 0, sizeof(surface_desc
));
5673 surface_desc
.dwSize
= sizeof(surface_desc
);
5674 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5675 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5676 surface_desc
.dwWidth
= 16;
5677 surface_desc
.dwHeight
= 16;
5678 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5679 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5681 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
5682 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5683 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5684 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5685 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
5686 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5687 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
5688 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5689 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
5690 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5691 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
5692 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5694 IDirectDrawSurface_Release(surface4
);
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
;
5699 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5700 surface_desc
.dwWidth
= 16;
5701 surface_desc
.dwHeight
= 16;
5702 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5703 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5705 if (SUCCEEDED(hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
)))
5707 skip("Running on refrast, skipping some tests.\n");
5708 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface4
);
5709 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5713 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5714 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5715 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5716 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
5717 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5718 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
5719 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5720 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
5721 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5722 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
5723 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5726 IDirectDrawSurface_Release(surface4
);
5727 IDirectDrawSurface_Release(surface3
);
5728 IDirectDrawSurface_Release(surface2
);
5729 IDirectDrawSurface_Release(surface1
);
5731 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5732 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5734 /* Try a single primary and two offscreen plain surfaces. */
5735 memset(&surface_desc
, 0, sizeof(surface_desc
));
5736 surface_desc
.dwSize
= sizeof(surface_desc
);
5737 surface_desc
.dwFlags
= DDSD_CAPS
;
5738 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
5739 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5740 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5742 memset(&surface_desc
, 0, sizeof(surface_desc
));
5743 surface_desc
.dwSize
= sizeof(surface_desc
);
5744 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5745 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5746 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
5747 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
5748 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
5749 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5751 memset(&surface_desc
, 0, sizeof(surface_desc
));
5752 surface_desc
.dwSize
= sizeof(surface_desc
);
5753 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5754 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5755 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
5756 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
5757 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
5758 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5760 /* This one has a different size. */
5761 memset(&surface_desc
, 0, sizeof(surface_desc
));
5762 surface_desc
.dwSize
= sizeof(surface_desc
);
5763 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5764 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5765 surface_desc
.dwWidth
= 128;
5766 surface_desc
.dwHeight
= 128;
5767 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5768 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5770 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5771 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5772 /* Try the reverse without detaching first. */
5773 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
5774 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
5775 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5776 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5778 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
5779 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5780 /* Try to detach reversed. */
5781 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5782 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5783 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface1
);
5784 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5786 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface3
);
5787 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5788 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface3
);
5789 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5791 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
5792 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5793 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5794 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5796 IDirectDrawSurface_Release(surface4
);
5797 IDirectDrawSurface_Release(surface3
);
5798 IDirectDrawSurface_Release(surface2
);
5799 IDirectDrawSurface_Release(surface1
);
5801 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
5802 memset(&surface_desc
, 0, sizeof(surface_desc
));
5803 surface_desc
.dwSize
= sizeof(surface_desc
);
5804 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5805 surface_desc
.dwWidth
= 64;
5806 surface_desc
.dwHeight
= 64;
5807 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
5808 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5809 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
5810 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
5811 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
5812 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
5813 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
5814 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5815 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5816 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
5817 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5819 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
5820 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
5821 U1(surface_desc
.ddpfPixelFormat
).dwZBufferBitDepth
= 16;
5822 U3(surface_desc
.ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
5823 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
5824 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5826 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5827 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5828 refcount
= get_refcount((IUnknown
*)surface2
);
5829 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5830 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5831 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
5833 /* Attaching while already attached to other surface. */
5834 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface2
);
5835 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5836 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface3
, 0, surface2
);
5837 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5838 IDirectDrawSurface_Release(surface3
);
5840 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5841 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5842 refcount
= get_refcount((IUnknown
*)surface2
);
5843 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5845 /* Automatic detachment on release. */
5846 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5847 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
5848 refcount
= get_refcount((IUnknown
*)surface2
);
5849 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5850 refcount
= IDirectDrawSurface_Release(surface1
);
5851 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5852 refcount
= IDirectDrawSurface_Release(surface2
);
5853 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5854 refcount
= IDirectDraw2_Release(ddraw
);
5855 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5856 DestroyWindow(window
);
5859 static void test_pixel_format(void)
5861 HWND window
, window2
= NULL
;
5862 HDC hdc
, hdc2
= NULL
;
5864 int format
, test_format
;
5865 PIXELFORMATDESCRIPTOR pfd
;
5866 IDirectDraw2
*ddraw
= NULL
;
5867 IDirectDrawClipper
*clipper
= NULL
;
5869 IDirectDrawSurface
*primary
= NULL
;
5873 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
5874 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
5877 skip("Failed to create window\n");
5881 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
5882 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
5884 hdc
= GetDC(window
);
5887 skip("Failed to get DC\n");
5892 hdc2
= GetDC(window2
);
5894 gl
= LoadLibraryA("opengl32.dll");
5895 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
5897 format
= GetPixelFormat(hdc
);
5898 ok(format
== 0, "new window has pixel format %d\n", format
);
5900 ZeroMemory(&pfd
, sizeof(pfd
));
5901 pfd
.nSize
= sizeof(pfd
);
5903 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
5904 pfd
.iPixelType
= PFD_TYPE_RGBA
;
5905 pfd
.iLayerType
= PFD_MAIN_PLANE
;
5906 format
= ChoosePixelFormat(hdc
, &pfd
);
5909 skip("no pixel format available\n");
5913 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
5915 skip("failed to set pixel format\n");
5919 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
5921 skip("failed to set pixel format on second window\n");
5924 ReleaseDC(window2
, hdc2
);
5929 ddraw
= create_ddraw();
5930 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5932 test_format
= GetPixelFormat(hdc
);
5933 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5935 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5938 skip("Failed to set cooperative level, hr %#x.\n", hr
);
5942 test_format
= GetPixelFormat(hdc
);
5943 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5947 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
5948 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
5949 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
5950 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
5952 test_format
= GetPixelFormat(hdc
);
5953 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5955 test_format
= GetPixelFormat(hdc2
);
5956 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5959 memset(&ddsd
, 0, sizeof(ddsd
));
5960 ddsd
.dwSize
= sizeof(ddsd
);
5961 ddsd
.dwFlags
= DDSD_CAPS
;
5962 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
5964 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
5965 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
5967 test_format
= GetPixelFormat(hdc
);
5968 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5972 test_format
= GetPixelFormat(hdc2
);
5973 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5978 hr
= IDirectDrawSurface2_SetClipper(primary
, clipper
);
5979 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
5981 test_format
= GetPixelFormat(hdc
);
5982 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5984 test_format
= GetPixelFormat(hdc2
);
5985 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5988 memset(&fx
, 0, sizeof(fx
));
5989 fx
.dwSize
= sizeof(fx
);
5990 hr
= IDirectDrawSurface2_Blt(primary
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
5991 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
5993 test_format
= GetPixelFormat(hdc
);
5994 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5998 test_format
= GetPixelFormat(hdc2
);
5999 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6003 if (primary
) IDirectDrawSurface2_Release(primary
);
6004 if (clipper
) IDirectDrawClipper_Release(clipper
);
6005 if (ddraw
) IDirectDraw2_Release(ddraw
);
6006 if (gl
) FreeLibrary(gl
);
6007 if (hdc
) ReleaseDC(window
, hdc
);
6008 if (hdc2
) ReleaseDC(window2
, hdc2
);
6009 if (window
) DestroyWindow(window
);
6010 if (window2
) DestroyWindow(window2
);
6013 static void test_create_surface_pitch(void)
6015 IDirectDrawSurface
*surface
;
6016 DDSURFACEDESC surface_desc
;
6017 IDirectDraw2
*ddraw
;
6037 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6039 DDSD_PITCH
, 0x100, 0x100},
6040 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6041 DDSD_PITCH
, 0x104, DD_OK
,
6042 DDSD_PITCH
, 0x100, 0x100},
6043 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6044 DDSD_PITCH
, 0x0f8, DD_OK
,
6045 DDSD_PITCH
, 0x100, 0x100},
6046 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6047 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
6049 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6051 DDSD_PITCH
, 0x100, 0x0fc},
6053 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6054 DDSD_PITCH
, 0x104, DD_OK
,
6055 DDSD_PITCH
, 0x100, 0x0fc},
6056 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6057 DDSD_PITCH
, 0x0f8, DD_OK
,
6058 DDSD_PITCH
, 0x100, 0x0fc},
6059 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6060 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
6061 DDSD_PITCH
, 0x100, 0x0fc},
6062 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6063 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
6065 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6066 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
6069 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
6070 0, 0, DDERR_INVALIDCAPS
,
6072 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6074 DDSD_PITCH
, 0x100, 0 },
6075 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6076 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
6078 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
6079 0, 0, DDERR_INVALIDCAPS
,
6081 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6083 DDSD_PITCH
, 0x100, 0 },
6085 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6086 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
6089 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
6091 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6092 0, 0, 640, 480, 0, 0, 0, 0);
6093 ddraw
= create_ddraw();
6094 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6095 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6096 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6098 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((63 * 4) + 8) * 63);
6100 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
6102 memset(&surface_desc
, 0, sizeof(surface_desc
));
6103 surface_desc
.dwSize
= sizeof(surface_desc
);
6104 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
6105 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
6106 surface_desc
.dwWidth
= 63;
6107 surface_desc
.dwHeight
= 63;
6108 U1(surface_desc
).lPitch
= test_data
[i
].pitch_in
;
6109 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6110 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6111 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6112 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6113 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6114 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6115 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6116 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
6118 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
6119 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, expected_hr
);
6120 surface_desc
.lpSurface
= mem
;
6121 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6123 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
6125 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
6129 memset(&surface_desc
, 0, sizeof(surface_desc
));
6130 surface_desc
.dwSize
= sizeof(surface_desc
);
6131 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
6132 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
6133 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
6134 "Test %u: Got unexpected flags %#x, expected %#x.\n",
6135 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
6136 /* The pitch for textures seems to be implementation specific. */
6137 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
6139 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
6140 todo_wine
ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out64
,
6141 "Test %u: Got unexpected pitch %u, expected %u.\n",
6142 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out64
);
6144 ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out32
,
6145 "Test %u: Got unexpected pitch %u, expected %u.\n",
6146 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out32
);
6148 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
6150 IDirectDrawSurface_Release(surface
);
6153 HeapFree(GetProcessHeap(), 0, mem
);
6154 refcount
= IDirectDraw2_Release(ddraw
);
6155 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6156 DestroyWindow(window
);
6159 static void test_mipmap(void)
6161 IDirectDrawSurface
*surface1
;
6162 IDirectDrawSurface2
*surface
, *surface2
;
6163 DDSURFACEDESC surface_desc
;
6164 IDirectDraw2
*ddraw
;
6169 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
6178 DWORD mipmap_count_in
;
6180 DWORD mipmap_count_out
;
6184 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
6185 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
, 0},
6186 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
6187 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
, 0},
6188 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 6},
6189 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 6},
6192 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6193 0, 0, 640, 480, 0, 0, 0, 0);
6194 ddraw
= create_ddraw();
6195 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6196 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6197 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6199 memset(&hal_caps
, 0, sizeof(hal_caps
));
6200 hal_caps
.dwSize
= sizeof(hal_caps
);
6201 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
6202 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
6203 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
6205 skip("Mipmapped textures not supported, skipping tests.\n");
6206 IDirectDraw2_Release(ddraw
);
6207 DestroyWindow(window
);
6211 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
6213 memset(&surface_desc
, 0, sizeof(surface_desc
));
6214 surface_desc
.dwSize
= sizeof(surface_desc
);
6215 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
6216 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
6217 surface_desc
.dwWidth
= tests
[i
].width
;
6218 surface_desc
.dwHeight
= tests
[i
].height
;
6219 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
6220 U2(surface_desc
).dwMipMapCount
= tests
[i
].mipmap_count_in
;
6221 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6222 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
6226 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
6227 ok(SUCCEEDED(hr
), "Test %u: Failed to get IDirectDrawSurface2 interface, hr %#x.\n", i
, hr
);
6228 IDirectDrawSurface_Release(surface1
);
6230 memset(&surface_desc
, 0, sizeof(surface_desc
));
6231 surface_desc
.dwSize
= sizeof(surface_desc
);
6232 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface
, &surface_desc
);
6233 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
6234 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
6235 "Test %u: Got unexpected flags %#x.\n", i
, surface_desc
.dwFlags
);
6236 ok(U2(surface_desc
).dwMipMapCount
== tests
[i
].mipmap_count_out
,
6237 "Test %u: Got unexpected mipmap count %u.\n", i
, U2(surface_desc
).dwMipMapCount
);
6239 if (U2(surface_desc
).dwMipMapCount
> 1)
6241 hr
= IDirectDrawSurface2_GetAttachedSurface(surface
, &caps
, &surface2
);
6242 ok(SUCCEEDED(hr
), "Test %u: Failed to get attached surface, hr %#x.\n", i
, hr
);
6244 memset(&surface_desc
, 0, sizeof(surface_desc
));
6245 surface_desc
.dwSize
= sizeof(surface_desc
);
6246 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
6247 ok(SUCCEEDED(hr
), "Test %u: Failed to lock surface, hr %#x.\n", i
, hr
);
6248 memset(&surface_desc
, 0, sizeof(surface_desc
));
6249 surface_desc
.dwSize
= sizeof(surface_desc
);
6250 hr
= IDirectDrawSurface2_Lock(surface2
, NULL
, &surface_desc
, 0, NULL
);
6251 ok(SUCCEEDED(hr
), "Test %u: Failed to lock surface, hr %#x.\n", i
, hr
);
6252 IDirectDrawSurface2_Unlock(surface2
, NULL
);
6253 IDirectDrawSurface2_Unlock(surface
, NULL
);
6255 IDirectDrawSurface2_Release(surface2
);
6258 IDirectDrawSurface2_Release(surface
);
6261 refcount
= IDirectDraw2_Release(ddraw
);
6262 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6263 DestroyWindow(window
);
6266 static void test_palette_complex(void)
6268 IDirectDrawSurface
*surface1
;
6269 IDirectDrawSurface2
*surface
, *mipmap
, *tmp
;
6270 DDSURFACEDESC surface_desc
;
6271 IDirectDraw2
*ddraw
;
6272 IDirectDrawPalette
*palette
, *palette2
, *palette_mipmap
;
6276 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
6278 PALETTEENTRY palette_entries
[256];
6284 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6285 0, 0, 640, 480, 0, 0, 0, 0);
6286 ddraw
= create_ddraw();
6287 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6288 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6289 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6291 memset(&hal_caps
, 0, sizeof(hal_caps
));
6292 hal_caps
.dwSize
= sizeof(hal_caps
);
6293 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
6294 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
6295 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
6297 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
6298 IDirectDraw2_Release(ddraw
);
6299 DestroyWindow(window
);
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
| DDSD_PIXELFORMAT
;
6306 surface_desc
.dwWidth
= 128;
6307 surface_desc
.dwHeight
= 128;
6308 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
6309 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6310 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
6311 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
6312 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6313 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6314 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
6315 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr
);
6316 IDirectDrawSurface_Release(surface1
);
6318 memset(palette_entries
, 0, sizeof(palette_entries
));
6319 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6320 palette_entries
, &palette
, NULL
);
6321 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6323 memset(palette_entries
, 0, sizeof(palette_entries
));
6324 palette_entries
[1].peRed
= 0xff;
6325 palette_entries
[1].peGreen
= 0x80;
6326 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6327 palette_entries
, &palette_mipmap
, NULL
);
6328 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6330 palette2
= (void *)0xdeadbeef;
6331 hr
= IDirectDrawSurface2_GetPalette(surface
, &palette2
);
6332 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
6333 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
6334 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
6335 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6336 hr
= IDirectDrawSurface2_GetPalette(surface
, &palette2
);
6337 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
6338 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
6339 IDirectDrawPalette_Release(palette2
);
6342 IDirectDrawSurface2_AddRef(mipmap
);
6343 for (i
= 0; i
< 7; ++i
)
6345 hr
= IDirectDrawSurface2_GetAttachedSurface(mipmap
, &caps
, &tmp
);
6346 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
6347 palette2
= (void *)0xdeadbeef;
6348 hr
= IDirectDrawSurface2_GetPalette(tmp
, &palette2
);
6349 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
6350 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
6352 hr
= IDirectDrawSurface2_SetPalette(tmp
, palette_mipmap
);
6353 ok(SUCCEEDED(hr
), "Failed to set palette, i %u, hr %#x.\n", i
, hr
);
6355 hr
= IDirectDrawSurface2_GetPalette(tmp
, &palette2
);
6356 ok(SUCCEEDED(hr
), "Failed to get palette, i %u, hr %#x.\n", i
, hr
);
6357 ok(palette_mipmap
== palette2
, "Got unexpected palette %p.\n", palette2
);
6358 IDirectDrawPalette_Release(palette2
);
6360 hr
= IDirectDrawSurface2_GetDC(tmp
, &dc
);
6361 ok(SUCCEEDED(hr
), "Failed to get DC, i %u, hr %#x.\n", i
, hr
);
6362 count
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
6363 ok(count
== 1, "Expected count 1, got %u.\n", count
);
6364 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x.\n", rgbquad
.rgbRed
);
6365 ok(rgbquad
.rgbGreen
== 0x80, "Expected rgbGreen = 0x80, got %#x.\n", rgbquad
.rgbGreen
);
6366 ok(rgbquad
.rgbBlue
== 0x0, "Expected rgbBlue = 0x0, got %#x.\n", rgbquad
.rgbBlue
);
6367 hr
= IDirectDrawSurface2_ReleaseDC(tmp
, dc
);
6368 ok(SUCCEEDED(hr
), "Failed to release DC, i %u, hr %#x.\n", i
, hr
);
6370 IDirectDrawSurface2_Release(mipmap
);
6374 hr
= IDirectDrawSurface2_GetAttachedSurface(mipmap
, &caps
, &tmp
);
6375 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
6376 IDirectDrawSurface2_Release(mipmap
);
6377 refcount
= IDirectDrawSurface2_Release(surface
);
6378 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6379 refcount
= IDirectDrawPalette_Release(palette_mipmap
);
6380 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6381 refcount
= IDirectDrawPalette_Release(palette
);
6382 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6384 refcount
= IDirectDraw2_Release(ddraw
);
6385 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6386 DestroyWindow(window
);
6389 static BOOL
ddraw_is_warp(IDirectDraw2
*ddraw
)
6391 IDirectDraw4
*ddraw4
;
6392 DDDEVICEIDENTIFIER identifier
;
6395 if (!strcmp(winetest_platform
, "wine"))
6398 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirectDraw4
, (void **)&ddraw4
);
6399 ok(SUCCEEDED(hr
), "Failed to get IDirectDraw4 interface, hr %#x.\n", hr
);
6400 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw4
, &identifier
, 0);
6401 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#x.\n", hr
);
6402 IDirectDraw4_Release(ddraw4
);
6403 return !!strstr(identifier
.szDriver
, "warp");
6406 static void test_p8_blit(void)
6408 IDirectDrawSurface
*src
, *dst
, *dst_p8
;
6409 DDSURFACEDESC surface_desc
;
6410 IDirectDraw2
*ddraw
;
6411 IDirectDrawPalette
*palette
, *palette2
;
6415 PALETTEENTRY palette_entries
[256];
6419 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
6420 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
6421 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
6422 static const D3DCOLOR expected
[] =
6424 0x00101010, 0x00010101, 0x00020202, 0x00030303,
6425 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
6429 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6430 0, 0, 640, 480, 0, 0, 0, 0);
6431 ddraw
= create_ddraw();
6432 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6433 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6434 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6435 is_warp
= ddraw_is_warp(ddraw
);
6437 memset(palette_entries
, 0, sizeof(palette_entries
));
6438 palette_entries
[1].peGreen
= 0xff;
6439 palette_entries
[2].peBlue
= 0xff;
6440 palette_entries
[3].peFlags
= 0xff;
6441 palette_entries
[4].peRed
= 0xff;
6442 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6443 palette_entries
, &palette
, NULL
);
6444 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6445 palette_entries
[1].peBlue
= 0xff;
6446 palette_entries
[2].peGreen
= 0xff;
6447 palette_entries
[3].peRed
= 0xff;
6448 palette_entries
[4].peFlags
= 0x0;
6449 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6450 palette_entries
, &palette2
, NULL
);
6451 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6453 memset(&surface_desc
, 0, sizeof(surface_desc
));
6454 surface_desc
.dwSize
= sizeof(surface_desc
);
6455 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6456 surface_desc
.dwWidth
= 8;
6457 surface_desc
.dwHeight
= 1;
6458 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6459 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6460 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
6461 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
6462 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
6463 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6464 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
6465 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6466 hr
= IDirectDrawSurface_SetPalette(dst_p8
, palette2
);
6467 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6469 memset(&surface_desc
, 0, sizeof(surface_desc
));
6470 surface_desc
.dwSize
= sizeof(surface_desc
);
6471 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6472 surface_desc
.dwWidth
= 8;
6473 surface_desc
.dwHeight
= 1;
6474 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6475 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6476 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
6477 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6478 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6479 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6480 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6481 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
6482 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
6483 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6485 memset(&surface_desc
, 0, sizeof(surface_desc
));
6486 surface_desc
.dwSize
= sizeof(surface_desc
);
6487 hr
= IDirectDrawSurface_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
6488 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
6489 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
6490 hr
= IDirectDrawSurface_Unlock(src
, NULL
);
6491 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
6493 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
6494 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
6495 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
6496 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
6497 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
6499 hr
= IDirectDrawSurface_SetPalette(src
, palette
);
6500 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6501 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
6502 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
6503 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
6504 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
6505 "Failed to blit, hr %#x.\n", hr
);
6509 for (x
= 0; x
< sizeof(expected
) / sizeof(*expected
); x
++)
6511 color
= get_surface_color(dst
, x
, 0);
6512 todo_wine
ok(compare_color(color
, expected
[x
], 0),
6513 "Pixel %u: Got color %#x, expected %#x.\n",
6514 x
, color
, expected
[x
]);
6518 memset(&fx
, 0, sizeof(fx
));
6519 fx
.dwSize
= sizeof(fx
);
6520 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
6521 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
6522 hr
= IDirectDrawSurface7_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
6523 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
6525 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
6526 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
6527 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
6528 * surface untouched. P8 blits without color keys work. Error checking (DDBLT_KEYSRC without a key
6529 * for example) also works as expected.
6531 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
6532 * the display mode set to P8 doesn't help either. */
6533 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
6534 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
6535 "Got unexpected P8 color key blit result.\n");
6536 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
6537 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
6539 IDirectDrawSurface_Release(src
);
6540 IDirectDrawSurface_Release(dst
);
6541 IDirectDrawSurface_Release(dst_p8
);
6542 IDirectDrawPalette_Release(palette
);
6543 IDirectDrawPalette_Release(palette2
);
6545 refcount
= IDirectDraw2_Release(ddraw
);
6546 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6547 DestroyWindow(window
);
6550 static void test_material(void)
6552 IDirect3DMaterial2
*background
, *material
;
6553 D3DMATERIALHANDLE mat_handle
, tmp
;
6554 IDirect3DViewport2
*viewport
;
6555 IDirect3DDevice2
*device
;
6556 IDirectDrawSurface
*rt
;
6557 IDirectDraw2
*ddraw
;
6565 static D3DVERTEX quad
[] =
6567 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6568 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6569 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6570 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6575 D3DCOLOR expected_color
;
6580 {FALSE
, 0x00ffffff},
6582 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
6584 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6585 0, 0, 640, 480, 0, 0, 0, 0);
6586 ddraw
= create_ddraw();
6587 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6588 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
6590 skip("Failed to create a 3D device, skipping test.\n");
6591 DestroyWindow(window
);
6595 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
6596 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
6598 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
6599 viewport
= create_viewport(device
, 0, 0, 640, 480);
6600 viewport_set_background(device
, viewport
, background
);
6601 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
6602 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
6604 material
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
6605 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
6606 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
6608 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
6609 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
6610 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
6611 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
6612 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
6613 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
6614 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
6615 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
6616 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, 0);
6617 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
6618 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
6619 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
6620 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
6622 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
6624 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
6625 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6627 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, test_data
[i
].material
? mat_handle
: 0);
6628 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
6630 hr
= IDirect3DDevice2_BeginScene(device
);
6631 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6632 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_VERTEX
, quad
, 4, 0);
6633 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6634 hr
= IDirect3DDevice2_EndScene(device
);
6635 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6636 color
= get_surface_color(rt
, 320, 240);
6637 ok(compare_color(color
, test_data
[i
].expected_color
, 1),
6638 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
6641 destroy_material(material
);
6642 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
6643 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
6644 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
6646 hr
= IDirect3DViewport2_SetBackground(viewport
, mat_handle
);
6647 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
6648 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
6649 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
6650 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
6651 ok(valid
, "Got unexpected valid %#x.\n", valid
);
6652 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6653 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6654 color
= get_surface_color(rt
, 320, 240);
6655 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
6657 hr
= IDirect3DViewport2_SetBackground(viewport
, 0);
6658 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
6659 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
6660 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
6661 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
6662 ok(valid
, "Got unexpected valid %#x.\n", valid
);
6663 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6664 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6665 color
= get_surface_color(rt
, 320, 240);
6666 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
6668 destroy_viewport(device
, viewport
);
6669 viewport
= create_viewport(device
, 0, 0, 640, 480);
6671 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
6672 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
6673 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
6674 ok(!valid
, "Got unexpected valid %#x.\n", valid
);
6675 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6676 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6677 color
= get_surface_color(rt
, 320, 240);
6678 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color
);
6680 destroy_viewport(device
, viewport
);
6681 destroy_material(background
);
6682 destroy_material(material
);
6683 IDirectDrawSurface_Release(rt
);
6684 refcount
= IDirect3DDevice2_Release(device
);
6685 ok(!refcount
, "Device has %u references left.\n", refcount
);
6686 refcount
= IDirectDraw2_Release(ddraw
);
6687 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
6688 DestroyWindow(window
);
6691 static void test_lighting(void)
6693 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
6694 static D3DMATRIX mat
=
6696 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6697 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6698 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6699 0.0f
, 0.0f
, 0.0f
, 1.0f
,
6703 1.0f
, 0.0f
, 1.0f
, 0.0f
,
6704 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6705 1.0f
, 0.0f
, 1.0f
, 0.0f
,
6706 0.0f
, 0.0f
, 0.5f
, 1.0f
,
6710 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6711 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6712 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
6713 10.f
, 10.0f
, 10.0f
, 1.0f
,
6717 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6718 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6719 0.0f
, 0.0f
, 1.0f
, -1.0f
,
6720 10.f
, 10.0f
, 10.0f
, 0.0f
,
6722 static D3DLVERTEX unlitquad
[] =
6724 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
6725 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
6726 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
6727 {{ 0.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
6731 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
6732 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
6733 {{ 0.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
6734 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
6736 static D3DVERTEX unlitnquad
[] =
6738 {{0.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6739 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6740 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6741 {{1.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6745 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6746 {{0.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6747 {{1.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6748 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6752 {{-1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6753 {{-1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6754 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6755 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6759 {{-10.0f
}, {-11.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
6760 {{-10.0f
}, { -9.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
6761 {{-10.0f
}, { -9.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
6762 {{-10.0f
}, {-11.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
6766 {{-11.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6767 {{-11.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6768 {{ -9.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6769 {{ -9.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6771 static WORD indices
[] = {0, 1, 2, 2, 3, 0};
6774 D3DMATRIX
*world_matrix
;
6777 const char *message
;
6781 {&mat
, nquad
, 0x000000ff, "Lit quad with light"},
6782 {&mat_singular
, nquad
, 0x000000b4, "Lit quad with singular world matrix"},
6783 {&mat_transf
, rotatedquad
, 0x000000ff, "Lit quad with transformation matrix"},
6784 {&mat_nonaffine
, translatedquad
, 0x000000ff, "Lit quad with non-affine matrix"},
6789 IDirect3DDevice2
*device
;
6790 IDirectDraw2
*ddraw
;
6791 IDirectDrawSurface
*rt
;
6792 IDirect3DViewport2
*viewport
;
6793 IDirect3DMaterial2
*material
;
6794 IDirect3DLight
*light
;
6795 D3DMATERIALHANDLE mat_handle
;
6796 D3DLIGHT2 light_desc
;
6802 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6803 0, 0, 640, 480, 0, 0, 0, 0);
6804 ddraw
= create_ddraw();
6805 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6806 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
6808 skip("Failed to create a 3D device, skipping test.\n");
6809 DestroyWindow(window
);
6813 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
6814 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
6816 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
6817 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
6819 viewport
= create_viewport(device
, 0, 0, 640, 480);
6820 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
6821 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
6823 material
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
6824 viewport_set_background(device
, viewport
, material
);
6826 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6827 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6829 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
6830 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
6831 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
6832 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
6833 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
6834 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
6835 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
6836 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
6837 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
6838 ok(SUCCEEDED(hr
), "Failed to disable zbuffer, hr %#x.\n", hr
);
6839 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
6840 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
6841 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
6842 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
6844 hr
= IDirect3DDevice2_BeginScene(device
);
6845 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6847 /* There is no D3DRENDERSTATE_LIGHTING on ddraw < 7. */
6848 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
6849 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
6850 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_LVERTEX
, unlitquad
,
6852 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6854 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
6855 ok(SUCCEEDED(hr
), "Failed to enable lighting, hr %#x.\n", hr
);
6856 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_LVERTEX
, litquad
,
6858 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6860 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
6861 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
6862 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, unlitnquad
,
6864 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6866 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
6867 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
6868 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, litnquad
,
6870 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6872 hr
= IDirect3DDevice2_EndScene(device
);
6873 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6875 color
= get_surface_color(rt
, 160, 360);
6876 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color
);
6877 color
= get_surface_color(rt
, 160, 120);
6878 ok(color
== 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color
);
6879 color
= get_surface_color(rt
, 480, 360);
6880 ok(color
== 0x00ffffff, "Unlit quad with normals has color 0x%08x.\n", color
);
6881 color
= get_surface_color(rt
, 480, 120);
6882 ok(color
== 0x00ffffff, "Lit quad with normals has color 0x%08x.\n", color
);
6884 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
6885 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
6886 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
6887 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
6889 hr
= IDirect3D2_CreateLight(d3d
, &light
, NULL
);
6890 ok(SUCCEEDED(hr
), "Failed to create a light object, hr %#x.\n", hr
);
6891 memset(&light_desc
, 0, sizeof(light_desc
));
6892 light_desc
.dwSize
= sizeof(light_desc
);
6893 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
6894 U1(light_desc
.dcvColor
).r
= 0.0f
;
6895 U2(light_desc
.dcvColor
).g
= 0.0f
;
6896 U3(light_desc
.dcvColor
).b
= 1.0f
;
6897 U4(light_desc
.dcvColor
).a
= 1.0f
;
6898 U3(light_desc
.dvDirection
).z
= 1.0f
;
6899 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
6900 ok(SUCCEEDED(hr
), "Failed to set light, hr %#x.\n", hr
);
6901 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
6902 ok(SUCCEEDED(hr
), "Failed to add a light to the viewport, hr %#x.\n", hr
);
6904 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6905 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6907 hr
= IDirect3DDevice2_BeginScene(device
);
6908 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6910 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, nquad
,
6912 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6914 hr
= IDirect3DDevice2_EndScene(device
);
6915 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6917 color
= get_surface_color(rt
, 320, 240);
6918 ok(color
== 0x00000000, "Lit quad with no light has color 0x%08x.\n", color
);
6920 light_desc
.dwFlags
= D3DLIGHT_ACTIVE
;
6921 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
6922 ok(SUCCEEDED(hr
), "Failed to set light, hr %#x.\n", hr
);
6924 for (i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); ++i
)
6926 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, tests
[i
].world_matrix
);
6927 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
6929 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6930 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6932 hr
= IDirect3DDevice2_BeginScene(device
);
6933 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6935 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
,
6936 tests
[i
].quad
, 4, indices
, 6, 0);
6937 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6939 hr
= IDirect3DDevice2_EndScene(device
);
6940 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6942 color
= get_surface_color(rt
, 320, 240);
6943 ok(color
== tests
[i
].expected
, "%s has color 0x%08x.\n", tests
[i
].message
, color
);
6946 hr
= IDirect3DViewport2_DeleteLight(viewport
, light
);
6947 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#x.\n", hr
);
6948 IDirect3DLight_Release(light
);
6949 destroy_material(material
);
6950 destroy_viewport(device
, viewport
);
6951 IDirectDrawSurface2_Release(rt
);
6952 refcount
= IDirect3DDevice2_Release(device
);
6953 ok(!refcount
, "Device has %u references left.\n", refcount
);
6954 IDirect3D2_Release(d3d
);
6955 refcount
= IDirectDraw2_Release(ddraw
);
6956 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
6957 DestroyWindow(window
);
6960 static void test_specular_lighting(void)
6962 static const unsigned int vertices_side
= 5;
6963 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
6964 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
6965 static D3DMATRIX mat
=
6967 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6968 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6969 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6970 0.0f
, 0.0f
, 0.0f
, 1.0f
,
6972 static D3DLIGHT2 directional
=
6975 D3DLIGHT_DIRECTIONAL
,
6976 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
6977 {{0.0f
}, {0.0f
}, {0.0f
}},
6978 {{0.0f
}, {0.0f
}, {1.0f
}},
6984 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
6985 {{0.0f
}, {0.0f
}, {0.0f
}},
6986 {{0.0f
}, {0.0f
}, {0.0f
}},
6995 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
6996 {{0.0f
}, {0.0f
}, {0.0f
}},
6997 {{0.0f
}, {0.0f
}, {1.0f
}},
7001 M_PI
/ 12.0f
, M_PI
/ 3.0f
7006 D3DLIGHT_PARALLELPOINT
,
7007 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7008 {{0.5f
}, {0.0f
}, {-1.0f
}},
7009 {{0.0f
}, {0.0f
}, {0.0f
}},
7011 static const struct expected_color
7016 expected_directional_local
[] =
7018 {160, 120, 0x003c3c3c},
7019 {320, 120, 0x00717171},
7020 {480, 120, 0x003c3c3c},
7021 {160, 240, 0x00717171},
7022 {320, 240, 0x00ffffff},
7023 {480, 240, 0x00717171},
7024 {160, 360, 0x003c3c3c},
7025 {320, 360, 0x00717171},
7026 {480, 360, 0x003c3c3c},
7028 expected_point_local
[] =
7030 {160, 120, 0x00000000},
7031 {320, 120, 0x00090909},
7032 {480, 120, 0x00000000},
7033 {160, 240, 0x00090909},
7034 {320, 240, 0x00fafafa},
7035 {480, 240, 0x00090909},
7036 {160, 360, 0x00000000},
7037 {320, 360, 0x00090909},
7038 {480, 360, 0x00000000},
7040 expected_spot_local
[] =
7042 {160, 120, 0x00000000},
7043 {320, 120, 0x00020202},
7044 {480, 120, 0x00000000},
7045 {160, 240, 0x00020202},
7046 {320, 240, 0x00fafafa},
7047 {480, 240, 0x00020202},
7048 {160, 360, 0x00000000},
7049 {320, 360, 0x00020202},
7050 {480, 360, 0x00000000},
7052 expected_parallelpoint
[] =
7054 {160, 120, 0x00050505},
7055 {320, 120, 0x002c2c2c},
7056 {480, 120, 0x006e6e6e},
7057 {160, 240, 0x00090909},
7058 {320, 240, 0x00717171},
7059 {480, 240, 0x00ffffff},
7060 {160, 360, 0x00050505},
7061 {320, 360, 0x002c2c2c},
7062 {480, 360, 0x006e6e6e},
7067 const struct expected_color
*expected
;
7068 unsigned int expected_count
;
7072 {&directional
, expected_directional_local
,
7073 sizeof(expected_directional_local
) / sizeof(expected_directional_local
[0])},
7074 {&point
, expected_point_local
,
7075 sizeof(expected_point_local
) / sizeof(expected_point_local
[0])},
7076 {&spot
, expected_spot_local
,
7077 sizeof(expected_spot_local
) / sizeof(expected_spot_local
[0])},
7078 {¶llelpoint
, expected_parallelpoint
,
7079 sizeof(expected_parallelpoint
) / sizeof(expected_parallelpoint
[0])},
7082 IDirect3DDevice2
*device
;
7083 IDirectDraw2
*ddraw
;
7084 IDirectDrawSurface
*rt
;
7085 IDirect3DViewport2
*viewport
;
7086 IDirect3DMaterial2
*material
, *background_material
;
7087 IDirect3DLight
*light
;
7088 D3DMATERIALHANDLE mat_handle
;
7093 unsigned int i
, j
, x
, y
;
7097 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
7098 0, 0, 640, 480, 0, 0, 0, 0);
7099 ddraw
= create_ddraw();
7100 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7101 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7103 skip("Failed to create a 3D device, skipping test.\n");
7104 DestroyWindow(window
);
7108 quad
= HeapAlloc(GetProcessHeap(), 0, vertices_side
* vertices_side
* sizeof(*quad
));
7109 indices
= HeapAlloc(GetProcessHeap(), 0, indices_count
* sizeof(*indices
));
7110 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
7112 for (x
= 0; x
< vertices_side
; ++x
)
7114 U1(quad
[i
]).x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
7115 U2(quad
[i
]).y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
7116 U3(quad
[i
]).z
= 1.0f
;
7117 U4(quad
[i
]).nx
= 0.0f
;
7118 U5(quad
[i
]).ny
= 0.0f
;
7119 U6(quad
[i
]).nz
= -1.0f
;
7120 U7(quad
[i
]).tu
= 0.0f
;
7121 U8(quad
[i
++]).tv
= 0.0f
;
7124 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
7126 for (x
= 0; x
< (vertices_side
- 1); ++x
)
7128 indices
[i
++] = y
* vertices_side
+ x
+ 1;
7129 indices
[i
++] = y
* vertices_side
+ x
;
7130 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
7131 indices
[i
++] = y
* vertices_side
+ x
+ 1;
7132 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
7133 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
7137 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
7138 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
7140 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
7141 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
7143 viewport
= create_viewport(device
, 0, 0, 640, 480);
7144 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
7145 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
7147 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
7148 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
7149 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
7150 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
7151 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
7152 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
7153 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
7154 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
7155 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
7156 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
7157 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
7158 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
7160 background_material
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
7161 viewport_set_background(device
, viewport
, background_material
);
7163 material
= create_specular_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, 30.0f
);
7164 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
7165 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
7166 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
7167 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
7169 hr
= IDirect3D2_CreateLight(d3d
, &light
, NULL
);
7170 ok(SUCCEEDED(hr
), "Failed to create a light object, hr %#x.\n", hr
);
7171 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
7172 ok(SUCCEEDED(hr
), "Failed to add a light to the viewport, hr %#x.\n", hr
);
7174 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
7175 ok(SUCCEEDED(hr
), "Failed to enable specular lighting, hr %#x.\n", hr
);
7177 for (i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); ++i
)
7179 tests
[i
].light
->dwFlags
= D3DLIGHT_ACTIVE
;
7180 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)tests
[i
].light
);
7181 ok(SUCCEEDED(hr
), "Failed to set light, hr %#x.\n", hr
);
7183 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7184 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
7186 hr
= IDirect3DDevice2_BeginScene(device
);
7187 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7189 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
,
7190 quad
, vertices_side
* vertices_side
, indices
, indices_count
, 0);
7191 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7193 hr
= IDirect3DDevice2_EndScene(device
);
7194 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7196 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
7198 color
= get_surface_color(rt
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
7199 ok(compare_color(color
, tests
[i
].expected
[j
].color
, 1),
7200 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
7201 tests
[i
].expected
[j
].color
, tests
[i
].expected
[j
].x
,
7202 tests
[i
].expected
[j
].y
, color
, i
);
7206 hr
= IDirect3DViewport2_DeleteLight(viewport
, light
);
7207 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#x.\n", hr
);
7208 IDirect3DLight_Release(light
);
7209 destroy_material(material
);
7210 destroy_material(background_material
);
7211 destroy_viewport(device
, viewport
);
7212 IDirectDrawSurface2_Release(rt
);
7213 refcount
= IDirect3DDevice2_Release(device
);
7214 ok(!refcount
, "Device has %u references left.\n", refcount
);
7215 IDirect3D2_Release(d3d
);
7216 refcount
= IDirectDraw2_Release(ddraw
);
7217 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
7218 DestroyWindow(window
);
7219 HeapFree(GetProcessHeap(), 0, indices
);
7220 HeapFree(GetProcessHeap(), 0, quad
);
7223 static void test_palette_gdi(void)
7225 IDirectDrawSurface
*surface
, *primary
;
7226 DDSURFACEDESC surface_desc
;
7227 IDirectDraw2
*ddraw
;
7228 IDirectDrawPalette
*palette
, *palette2
;
7232 PALETTEENTRY palette_entries
[256];
7238 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
7239 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
7240 * not the point of this test. */
7241 static const RGBQUAD expected1
[] =
7243 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
7244 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
7246 static const RGBQUAD expected2
[] =
7248 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
7249 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
7251 static const RGBQUAD expected3
[] =
7253 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
7254 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
7256 HPALETTE ddraw_palette_handle
;
7257 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
7258 RGBQUAD rgbquad
[255];
7259 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
7261 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
7262 0, 0, 640, 480, 0, 0, 0, 0);
7263 ddraw
= create_ddraw();
7264 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7265 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7266 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7268 memset(&surface_desc
, 0, sizeof(surface_desc
));
7269 surface_desc
.dwSize
= sizeof(surface_desc
);
7270 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7271 surface_desc
.dwWidth
= 16;
7272 surface_desc
.dwHeight
= 16;
7273 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7274 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7275 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
7276 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
7277 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7278 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7280 /* Avoid colors from the Windows default palette. */
7281 memset(palette_entries
, 0, sizeof(palette_entries
));
7282 palette_entries
[1].peRed
= 0x01;
7283 palette_entries
[2].peGreen
= 0x02;
7284 palette_entries
[3].peBlue
= 0x03;
7285 palette_entries
[4].peRed
= 0x13;
7286 palette_entries
[4].peGreen
= 0x14;
7287 palette_entries
[4].peBlue
= 0x15;
7288 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7289 palette_entries
, &palette
, NULL
);
7290 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7292 /* If there is no palette assigned and the display mode is not 8 bpp, some
7293 * drivers refuse to create a DC while others allow it. If a DC is created,
7294 * the DIB color table is uninitialized and contains random colors. No error
7295 * is generated when trying to read pixels and random garbage is returned.
7297 * The most likely explanation is that if the driver creates a DC, it (or
7298 * the higher-level runtime) uses GetSystemPaletteEntries to find the
7299 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
7300 * contains uninitialized garbage. See comments below for the P8 case. */
7302 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
7303 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7304 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7305 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7306 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
7307 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
7308 "Got unexpected palette %p, expected %p.\n",
7309 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
7311 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
7312 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
7313 for (i
= 0; i
< sizeof(expected1
) / sizeof(*expected1
); i
++)
7315 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
7316 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7317 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7318 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
7320 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
7322 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7323 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7324 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7327 /* Update the palette while the DC is in use. This does not modify the DC. */
7328 palette_entries
[4].peRed
= 0x23;
7329 palette_entries
[4].peGreen
= 0x24;
7330 palette_entries
[4].peBlue
= 0x25;
7331 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
7332 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#x.\n", hr
);
7334 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
7335 ok(i
== 1, "Expected count 1, got %u.\n", i
);
7336 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
7337 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7338 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
7339 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
7341 /* Neither does re-setting the palette. */
7342 hr
= IDirectDrawSurface_SetPalette(surface
, NULL
);
7343 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7344 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
7345 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7347 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
7348 ok(i
== 1, "Expected count 1, got %u.\n", i
);
7349 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
7350 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7351 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
7352 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
7354 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7355 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7357 /* Refresh the DC. This updates the palette. */
7358 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7359 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7360 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
7361 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
7362 for (i
= 0; i
< sizeof(expected2
) / sizeof(*expected2
); i
++)
7364 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
7365 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7366 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7367 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
7369 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
7371 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7372 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7373 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7375 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7376 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7378 refcount
= IDirectDrawSurface_Release(surface
);
7379 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7381 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
7382 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7383 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
7385 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
7386 IDirectDrawPalette_Release(palette
);
7387 IDirectDraw2_Release(ddraw
);
7388 DestroyWindow(window
);
7391 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
7393 memset(&surface_desc
, 0, sizeof(surface_desc
));
7394 surface_desc
.dwSize
= sizeof(surface_desc
);
7395 surface_desc
.dwFlags
= DDSD_CAPS
;
7396 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7397 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
7398 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7400 memset(&fx
, 0, sizeof(fx
));
7401 fx
.dwSize
= sizeof(fx
);
7403 SetRect(&r
, 0, 0, 319, 479);
7404 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7405 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
7406 SetRect(&r
, 320, 0, 639, 479);
7408 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7409 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
7411 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
7412 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7413 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
7414 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7416 color
= GetPixel(dc
, 160, 240);
7417 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
7418 color
= GetPixel(dc
, 480, 240);
7419 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
7421 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
7422 /* Windows 2000 on the testbot assigns a different palette to the primary. Refrast? */
7423 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
) || broken(TRUE
),
7424 "Got unexpected palette %p, expected %p.\n",
7425 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
7426 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
7428 /* The primary uses the system palette. In exclusive mode, the system palette matches
7429 * the ddraw palette attached to the primary, so the result is what you would expect
7430 * from a regular surface. Tests for the interaction between the ddraw palette and
7431 * the system palette are not included pending an application that depends on this.
7432 * The relation between those causes problems on Windows Vista and newer for games
7433 * like Age of Empires or StarCraft. Don't emulate it without a real need. */
7434 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
7435 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
7436 for (i
= 0; i
< sizeof(expected2
) / sizeof(*expected2
); i
++)
7438 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
7439 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7440 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7441 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
7443 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
7445 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7446 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7447 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7449 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
7450 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7452 memset(&surface_desc
, 0, sizeof(surface_desc
));
7453 surface_desc
.dwSize
= sizeof(surface_desc
);
7454 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7455 surface_desc
.dwWidth
= 16;
7456 surface_desc
.dwHeight
= 16;
7457 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7458 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7459 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7461 /* Here the offscreen surface appears to use the primary's palette,
7462 * but in all likelihood it is actually the system palette. */
7463 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7464 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7465 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
7466 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
7467 for (i
= 0; i
< sizeof(expected2
) / sizeof(*expected2
); i
++)
7469 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
7470 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7471 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7472 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
7474 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
7476 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7477 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7478 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7480 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7481 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7483 /* On real hardware a change to the primary surface's palette applies immediately,
7484 * even on device contexts from offscreen surfaces that do not have their own
7485 * palette. On the testbot VMs this is not the case. Don't test this until we
7486 * know of an application that depends on this. */
7488 memset(palette_entries
, 0, sizeof(palette_entries
));
7489 palette_entries
[1].peBlue
= 0x40;
7490 palette_entries
[2].peRed
= 0x40;
7491 palette_entries
[3].peGreen
= 0x40;
7492 palette_entries
[4].peRed
= 0x12;
7493 palette_entries
[4].peGreen
= 0x34;
7494 palette_entries
[4].peBlue
= 0x56;
7495 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7496 palette_entries
, &palette2
, NULL
);
7497 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7498 hr
= IDirectDrawSurface_SetPalette(surface
, palette2
);
7499 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7501 /* A palette assigned to the offscreen surface overrides the primary / system
7503 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7504 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7505 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
7506 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
7507 for (i
= 0; i
< sizeof(expected3
) / sizeof(*expected3
); i
++)
7509 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
7510 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7511 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7512 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
7514 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
7516 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7517 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7518 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7520 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7521 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7523 refcount
= IDirectDrawSurface_Release(surface
);
7524 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7526 /* The Windows 8 testbot keeps extra references to the primary and
7527 * backbuffer while in 8 bpp mode. */
7528 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
7529 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
7531 refcount
= IDirectDrawSurface_Release(primary
);
7532 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7533 refcount
= IDirectDrawPalette_Release(palette2
);
7534 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7535 refcount
= IDirectDrawPalette_Release(palette
);
7536 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7537 refcount
= IDirectDraw2_Release(ddraw
);
7538 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7539 DestroyWindow(window
);
7542 static void test_palette_alpha(void)
7544 IDirectDrawSurface
*surface1
;
7545 IDirectDrawSurface2
*surface
;
7546 DDSURFACEDESC surface_desc
;
7547 IDirectDraw2
*ddraw
;
7548 IDirectDrawPalette
*palette
;
7552 PALETTEENTRY palette_entries
[256];
7557 BOOL attach_allowed
;
7562 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
7563 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
7564 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
7567 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
7568 0, 0, 640, 480, 0, 0, 0, 0);
7569 ddraw
= create_ddraw();
7570 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7571 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
7573 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
7574 IDirectDraw2_Release(ddraw
);
7575 DestroyWindow(window
);
7578 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7579 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7581 memset(palette_entries
, 0, sizeof(palette_entries
));
7582 palette_entries
[1].peFlags
= 0x42;
7583 palette_entries
[2].peFlags
= 0xff;
7584 palette_entries
[3].peFlags
= 0x80;
7585 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
7586 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7588 memset(palette_entries
, 0x66, sizeof(palette_entries
));
7589 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
7590 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
7591 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7592 palette_entries
[0].peFlags
);
7593 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7594 palette_entries
[1].peFlags
);
7595 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
7596 palette_entries
[2].peFlags
);
7597 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
7598 palette_entries
[3].peFlags
);
7600 IDirectDrawPalette_Release(palette
);
7602 memset(palette_entries
, 0, sizeof(palette_entries
));
7603 palette_entries
[1].peFlags
= 0x42;
7604 palette_entries
[1].peRed
= 0xff;
7605 palette_entries
[2].peFlags
= 0xff;
7606 palette_entries
[3].peFlags
= 0x80;
7607 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
7608 palette_entries
, &palette
, NULL
);
7609 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7611 memset(palette_entries
, 0x66, sizeof(palette_entries
));
7612 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
7613 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
7614 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7615 palette_entries
[0].peFlags
);
7616 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7617 palette_entries
[1].peFlags
);
7618 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
7619 palette_entries
[2].peFlags
);
7620 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
7621 palette_entries
[3].peFlags
);
7623 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); i
++)
7625 memset(&surface_desc
, 0, sizeof(surface_desc
));
7626 surface_desc
.dwSize
= sizeof(surface_desc
);
7627 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
7628 surface_desc
.dwWidth
= 128;
7629 surface_desc
.dwHeight
= 128;
7630 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
7631 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7632 ok(SUCCEEDED(hr
), "Failed to create %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
7633 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
7634 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr
);
7635 IDirectDrawSurface_Release(surface1
);
7637 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
7638 if (test_data
[i
].attach_allowed
)
7639 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
7641 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
7649 hr
= IDirectDrawSurface2_GetDC(surface
, &dc
);
7650 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_CANTCREATEDC
) /* Win2k testbot */,
7651 "Failed to get DC, hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
7654 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
7655 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
7656 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
7657 rgbquad
.rgbRed
, test_data
[i
].name
);
7658 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
7659 rgbquad
.rgbGreen
, test_data
[i
].name
);
7660 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
7661 rgbquad
.rgbBlue
, test_data
[i
].name
);
7662 todo_wine
ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
7663 rgbquad
.rgbReserved
, test_data
[i
].name
);
7664 hr
= IDirectDrawSurface2_ReleaseDC(surface
, dc
);
7665 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7668 IDirectDrawSurface2_Release(surface
);
7671 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
7672 memset(&surface_desc
, 0, sizeof(surface_desc
));
7673 surface_desc
.dwSize
= sizeof(surface_desc
);
7674 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7675 surface_desc
.dwWidth
= 128;
7676 surface_desc
.dwHeight
= 128;
7677 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7678 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7679 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7680 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
7681 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7682 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7683 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7684 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7685 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7686 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
7687 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr
);
7688 IDirectDrawSurface_Release(surface1
);
7690 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
7691 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
7692 IDirectDrawSurface2_Release(surface
);
7694 /* The Windows 8 testbot keeps extra references to the primary
7695 * while in 8 bpp mode. */
7696 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
7697 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
7699 refcount
= IDirectDrawPalette_Release(palette
);
7700 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7701 refcount
= IDirectDraw2_Release(ddraw
);
7702 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7703 DestroyWindow(window
);
7706 static void test_lost_device(void)
7708 IDirectDrawSurface
*surface
;
7709 DDSURFACEDESC surface_desc
;
7710 HWND window1
, window2
;
7711 IDirectDraw2
*ddraw
;
7716 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
7717 0, 0, 640, 480, 0, 0, 0, 0);
7718 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
7719 0, 0, 640, 480, 0, 0, 0, 0);
7720 ddraw
= create_ddraw();
7721 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7722 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7723 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7725 memset(&surface_desc
, 0, sizeof(surface_desc
));
7726 surface_desc
.dwSize
= sizeof(surface_desc
);
7727 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
7728 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
7729 surface_desc
.dwBackBufferCount
= 1;
7730 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7731 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7733 hr
= IDirectDrawSurface_IsLost(surface
);
7734 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7735 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
7736 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7738 ret
= SetForegroundWindow(GetDesktopWindow());
7739 ok(ret
, "Failed to set foreground window.\n");
7740 hr
= IDirectDrawSurface_IsLost(surface
);
7741 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7742 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
7743 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7745 ret
= SetForegroundWindow(window1
);
7746 ok(ret
, "Failed to set foreground window.\n");
7747 hr
= IDirectDrawSurface_IsLost(surface
);
7748 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7749 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
7750 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7752 hr
= restore_surfaces(ddraw
);
7753 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7754 hr
= IDirectDrawSurface_IsLost(surface
);
7755 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7756 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
7757 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7759 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
7760 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7761 hr
= IDirectDrawSurface_IsLost(surface
);
7762 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7763 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
7764 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7766 /* Trying to restore the primary will crash, probably because flippable
7767 * surfaces can't exist in DDSCL_NORMAL. */
7768 IDirectDrawSurface_Release(surface
);
7769 memset(&surface_desc
, 0, sizeof(surface_desc
));
7770 surface_desc
.dwSize
= sizeof(surface_desc
);
7771 surface_desc
.dwFlags
= DDSD_CAPS
;
7772 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7773 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7774 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7776 hr
= IDirectDrawSurface_IsLost(surface
);
7777 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7779 ret
= SetForegroundWindow(GetDesktopWindow());
7780 ok(ret
, "Failed to set foreground window.\n");
7781 hr
= IDirectDrawSurface_IsLost(surface
);
7782 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7784 ret
= SetForegroundWindow(window1
);
7785 ok(ret
, "Failed to set foreground window.\n");
7786 hr
= IDirectDrawSurface_IsLost(surface
);
7787 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7789 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7790 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7791 hr
= IDirectDrawSurface_IsLost(surface
);
7792 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7794 hr
= restore_surfaces(ddraw
);
7795 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7796 hr
= IDirectDrawSurface_IsLost(surface
);
7797 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7799 IDirectDrawSurface_Release(surface
);
7800 memset(&surface_desc
, 0, sizeof(surface_desc
));
7801 surface_desc
.dwSize
= sizeof(surface_desc
);
7802 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
7803 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
7804 U5(surface_desc
).dwBackBufferCount
= 1;
7805 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7806 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7808 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7809 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7810 hr
= IDirectDrawSurface_IsLost(surface
);
7811 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7812 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
7813 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7815 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
7816 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7817 hr
= IDirectDrawSurface_IsLost(surface
);
7818 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7819 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
7820 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
7822 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
7823 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7824 hr
= IDirectDrawSurface_IsLost(surface
);
7825 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7826 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
7827 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
7829 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
7830 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7831 hr
= IDirectDrawSurface_IsLost(surface
);
7832 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7833 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
7834 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
7836 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
7837 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7838 hr
= IDirectDrawSurface_IsLost(surface
);
7839 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7840 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
7841 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
7843 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7844 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7845 hr
= IDirectDrawSurface_IsLost(surface
);
7846 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7847 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
7848 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7850 IDirectDrawSurface_Release(surface
);
7851 refcount
= IDirectDraw2_Release(ddraw
);
7852 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7853 DestroyWindow(window2
);
7854 DestroyWindow(window1
);
7857 static void test_surface_desc_lock(void)
7859 IDirectDrawSurface
*surface
;
7860 DDSURFACEDESC surface_desc
;
7861 IDirectDraw2
*ddraw
;
7866 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
7867 0, 0, 640, 480, 0, 0, 0, 0);
7868 ddraw
= create_ddraw();
7869 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7870 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7871 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7873 memset(&surface_desc
, 0, sizeof(surface_desc
));
7874 surface_desc
.dwSize
= sizeof(surface_desc
);
7875 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7876 surface_desc
.dwWidth
= 16;
7877 surface_desc
.dwHeight
= 16;
7878 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7879 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7880 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7882 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
7883 surface_desc
.dwSize
= sizeof(surface_desc
);
7884 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
7885 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7886 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
7888 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
7889 surface_desc
.dwSize
= sizeof(surface_desc
);
7890 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
7891 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
7892 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
7893 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
7894 surface_desc
.dwSize
= sizeof(surface_desc
);
7895 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
7896 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7897 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
7898 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
7899 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
7901 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
7902 surface_desc
.dwSize
= sizeof(surface_desc
);
7903 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
7904 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7905 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
7907 IDirectDrawSurface_Release(surface
);
7908 refcount
= IDirectDraw2_Release(ddraw
);
7909 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7910 DestroyWindow(window
);
7913 static void test_texturemapblend(void)
7918 static RECT rect
= {0, 0, 64, 128};
7919 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
7921 IDirectDrawSurface
*surface
, *rt
;
7922 IDirect3DTexture2
*texture
;
7923 D3DTEXTUREHANDLE texture_handle
;
7925 IDirectDraw2
*ddraw
;
7926 IDirect3DDevice2
*device
;
7927 IDirect3DMaterial2
*material
;
7928 IDirect3DViewport2
*viewport
;
7932 static D3DTLVERTEX test1_quads
[] =
7934 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {0.0f
}},
7935 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {1.0f
}},
7936 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {0.0f
}},
7937 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {1.0f
}},
7938 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {0.0f
}},
7939 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {1.0f
}},
7940 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {0.0f
}},
7941 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {1.0f
}},
7945 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {0.0f
}},
7946 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {1.0f
}},
7947 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {0.0f
}},
7948 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {1.0f
}},
7949 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {0.0f
}},
7950 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {1.0f
}},
7951 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {0.0f
}},
7952 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {1.0f
}},
7955 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
7956 0, 0, 640, 480, 0, 0, 0, 0);
7957 ddraw
= create_ddraw();
7958 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7959 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7961 skip("Failed to create a 3D device, skipping test.\n");
7962 DestroyWindow(window
);
7963 IDirectDraw2_Release(ddraw
);
7967 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
7968 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
7970 material
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
7971 viewport
= create_viewport(device
, 0, 0, 640, 480);
7972 viewport_set_background(device
, viewport
, material
);
7973 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
7974 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
7976 /* Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel.
7978 * The vertex alpha is completely ignored in this case, so case 1 and 2 combined are not
7979 * a D3DTOP_MODULATE with texture alpha = 0xff in case 2 (no alpha in texture). */
7980 memset(&ddsd
, 0, sizeof(ddsd
));
7981 ddsd
.dwSize
= sizeof(ddsd
);
7982 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
7983 ddsd
.dwHeight
= 128;
7985 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
7986 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
7987 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
7988 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
7989 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7990 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7991 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7992 U5(ddsd
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
7993 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7994 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7996 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
7997 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
7998 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
7999 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
8000 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8001 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8003 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8004 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
8006 memset(&fx
, 0, sizeof(fx
));
8007 fx
.dwSize
= sizeof(fx
);
8008 U5(fx
).dwFillColor
= 0xff0000ff;
8009 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8010 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8011 U5(fx
).dwFillColor
= 0x800000ff;
8012 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8013 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8015 /* Note that the ddraw1 version of this test runs tests 1-3 with D3DRENDERSTATE_COLORKEYENABLE
8016 * enabled, whereas this version only runs test 4 with color keying on. Because no color key
8017 * is set on the texture this should not result in different behavior. */
8018 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
8019 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8020 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
8021 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8022 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
8023 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8024 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
8025 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8026 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
8027 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8028 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
8029 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8031 hr
= IDirect3DDevice2_BeginScene(device
);
8032 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8033 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
8034 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8035 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
8036 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8037 hr
= IDirect3DDevice2_EndScene(device
);
8038 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8040 color
= get_surface_color(rt
, 5, 5);
8041 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
8042 color
= get_surface_color(rt
, 400, 5);
8043 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8044 color
= get_surface_color(rt
, 5, 245);
8045 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
8046 color
= get_surface_color(rt
, 400, 245);
8047 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8049 IDirect3DTexture2_Release(texture
);
8050 ref
= IDirectDrawSurface_Release(surface
);
8051 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
8053 /* Test alpha with texture that has no alpha channel - alpha should be taken from diffuse vertex color. */
8054 memset(&ddsd
, 0, sizeof(ddsd
));
8055 ddsd
.dwSize
= sizeof(ddsd
);
8056 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8057 ddsd
.dwHeight
= 128;
8059 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8060 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8061 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8062 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8063 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8064 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8065 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8067 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8068 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8070 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
8071 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
8072 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
8073 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
8074 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8075 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8077 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8078 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
8080 U5(fx
).dwFillColor
= 0xff0000ff;
8081 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8082 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8083 U5(fx
).dwFillColor
= 0x800000ff;
8084 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8085 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8087 hr
= IDirect3DDevice2_BeginScene(device
);
8088 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8089 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
8090 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8091 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
8092 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8093 hr
= IDirect3DDevice2_EndScene(device
);
8094 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8096 color
= get_surface_color(rt
, 5, 5);
8097 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8098 color
= get_surface_color(rt
, 400, 5);
8099 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8100 color
= get_surface_color(rt
, 5, 245);
8101 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
8102 color
= get_surface_color(rt
, 400, 245);
8103 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
8105 IDirect3DTexture2_Release(texture
);
8106 ref
= IDirectDrawSurface_Release(surface
);
8107 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
8109 /* Test RGB - should multiply color components from diffuse vertex color and texture. */
8110 memset(&ddsd
, 0, sizeof(ddsd
));
8111 ddsd
.dwSize
= sizeof(ddsd
);
8112 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8113 ddsd
.dwHeight
= 128;
8115 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8116 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8117 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
8118 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8119 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8120 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8121 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8122 U5(ddsd
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
8123 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8124 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8126 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
8127 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
8128 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
8129 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
8130 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8131 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8133 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8134 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
8136 U5(fx
).dwFillColor
= 0x00ffffff;
8137 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8138 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8139 U5(fx
).dwFillColor
= 0x00ffff80;
8140 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8141 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8143 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
8144 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8146 hr
= IDirect3DDevice2_BeginScene(device
);
8147 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8148 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test2_quads
[0], 4, 0);
8149 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8150 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test2_quads
[4], 4, 0);
8151 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8152 hr
= IDirect3DDevice2_EndScene(device
);
8153 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8155 color
= get_surface_color(rt
, 5, 5);
8156 ok(compare_color(color
, 0x00ff0040, 2), "Got unexpected color 0x%08x.\n", color
);
8157 color
= get_surface_color(rt
, 400, 5);
8158 ok(compare_color(color
, 0x00ff0080, 2), "Got unexpected color 0x%08x.\n", color
);
8159 color
= get_surface_color(rt
, 5, 245);
8160 ok(compare_color(color
, 0x00800080, 2), "Got unexpected color 0x%08x.\n", color
);
8161 color
= get_surface_color(rt
, 400, 245);
8162 ok(compare_color(color
, 0x008000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8164 IDirect3DTexture2_Release(texture
);
8165 ref
= IDirectDrawSurface_Release(surface
);
8166 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
8168 /* Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere). */
8169 memset(&ddsd
, 0, sizeof(ddsd
));
8170 ddsd
.dwSize
= sizeof(ddsd
);
8171 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8172 ddsd
.dwHeight
= 128;
8174 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8175 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8176 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8177 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 16;
8178 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
8179 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
8180 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
8182 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8183 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8185 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
8186 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
8187 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
8188 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
8189 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8190 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8192 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8193 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
8195 U5(fx
).dwFillColor
= 0xf800;
8196 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8197 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8198 U5(fx
).dwFillColor
= 0x001f;
8199 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8200 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8202 ckey
.dwColorSpaceLowValue
= 0x001f;
8203 ckey
.dwColorSpaceHighValue
= 0x001f;
8204 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
8205 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
8207 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
8208 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8209 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
8210 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8212 hr
= IDirect3DDevice2_BeginScene(device
);
8213 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8214 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
8215 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8216 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
8217 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8218 hr
= IDirect3DDevice2_EndScene(device
);
8219 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8221 color
= get_surface_color(rt
, 5, 5);
8222 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
8223 color
= get_surface_color(rt
, 400, 5);
8224 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
8225 color
= get_surface_color(rt
, 5, 245);
8226 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
8227 color
= get_surface_color(rt
, 400, 245);
8228 ok(compare_color(color
, 0x00800000, 2), "Got unexpected color 0x%08x.\n", color
);
8230 IDirect3DTexture2_Release(texture
);
8231 ref
= IDirectDrawSurface_Release(surface
);
8232 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
8234 destroy_viewport(device
, viewport
);
8235 ref
= IDirect3DMaterial2_Release(material
);
8236 ok(ref
== 0, "Material not properly released, refcount %u.\n", ref
);
8237 IDirectDrawSurface_Release(rt
);
8238 IDirect3DDevice2_Release(device
);
8239 ref
= IDirectDraw2_Release(ddraw
);
8240 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
8241 DestroyWindow(window
);
8244 static void test_viewport_clear_rect(void)
8247 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8248 static D3DRECT clear_rect2
= {{90}, {90}, {110}, {110}};
8249 IDirectDrawSurface
*rt
;
8251 IDirectDraw2
*ddraw
;
8252 IDirect3DDevice2
*device
;
8253 IDirect3DMaterial2
*red
, *green
;
8254 IDirect3DViewport2
*viewport
, *viewport2
;
8258 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8259 0, 0, 640, 480, 0, 0, 0, 0);
8260 ddraw
= create_ddraw();
8261 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8262 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8264 skip("Failed to create a 3D device, skipping test.\n");
8265 DestroyWindow(window
);
8266 IDirectDraw2_Release(ddraw
);
8270 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
8271 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
8273 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
8274 viewport
= create_viewport(device
, 0, 0, 640, 480);
8275 viewport_set_background(device
, viewport
, red
);
8276 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8277 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8279 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
8280 viewport2
= create_viewport(device
, 100, 100, 20, 20);
8281 viewport_set_background(device
, viewport2
, green
);
8282 hr
= IDirect3DViewport2_Clear(viewport2
, 1, &clear_rect2
, D3DCLEAR_TARGET
);
8283 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8285 color
= get_surface_color(rt
, 85, 85); /* Outside both. */
8286 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8287 color
= get_surface_color(rt
, 95, 95); /* Outside vp, inside rect. */
8288 /* AMD GPUs ignore the viewport dimensions and only care about the rectangle. */
8289 ok(compare_color(color
, 0x00ff0000, 1) || broken(compare_color(color
, 0x0000ff00, 1)),
8290 "Got unexpected color 0x%08x.\n", color
);
8291 color
= get_surface_color(rt
, 105, 105); /* Inside both. */
8292 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
8293 color
= get_surface_color(rt
, 115, 115); /* Inside vp, outside rect. */
8294 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8295 color
= get_surface_color(rt
, 125, 125); /* Outside both. */
8296 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8298 destroy_viewport(device
, viewport2
);
8299 destroy_material(green
);
8300 destroy_viewport(device
, viewport
);
8301 destroy_material(red
);
8302 IDirectDrawSurface_Release(rt
);
8303 IDirect3DDevice2_Release(device
);
8304 ref
= IDirectDraw2_Release(ddraw
);
8305 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
8306 DestroyWindow(window
);
8309 static void test_color_fill(void)
8312 IDirect3DDevice2
*device
;
8313 IDirectDraw2
*ddraw
;
8314 IDirectDrawSurface
*surface
, *surface2
;
8315 DDSURFACEDESC surface_desc
;
8320 RECT rect
= {5, 5, 7, 7};
8322 DWORD num_fourcc_codes
, *fourcc_codes
;
8324 BOOL support_uyvy
= FALSE
, support_yuy2
= FALSE
;
8328 HRESULT colorfill_hr
, depthfill_hr
;
8333 DDPIXELFORMAT format
;
8338 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
8339 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
8341 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
8342 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
8346 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
8347 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
8349 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
8350 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
8354 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
8355 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
8357 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
8358 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
8362 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
8363 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
8365 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
8366 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
8370 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
,
8371 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0, FALSE
,
8372 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
8375 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
8376 * different afterwards. DX9+ GPUs set one of the two luminance values
8377 * in each block, but AMD and Nvidia GPUs disagree on which luminance
8378 * value they set. r200 (dx8) just sets the entire block to the clear
8380 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
8381 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
8383 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
8384 {0}, {0}, {0}, {0}, {0}
8388 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
8389 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
8391 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
8392 {0}, {0}, {0}, {0}, {0}
8396 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
8397 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
8399 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
8400 {0}, {0}, {0}, {0}, {0}
8404 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
8405 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
8407 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
8408 {0}, {0}, {0}, {0}, {0}
8412 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
8413 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
8415 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
8416 {0}, {0}, {0}, {0}, {0}
8420 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
8421 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
8423 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
8424 {0}, {0}, {0}, {0}, {0}
8428 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
8429 * surface works, presumably because it is handled by the runtime instead of
8431 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
8432 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
8434 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
8435 {8}, {0}, {0}, {0}, {0}
8439 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
8440 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
8442 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
8443 {8}, {0}, {0}, {0}, {0}
8455 {SRCCOPY
, "SRCCOPY", DD_OK
},
8456 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
8457 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
8458 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
8459 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
8460 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
8461 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
8462 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
8463 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
8464 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
8465 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
8466 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
8467 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
8468 {BLACKNESS
, "BLACKNESS", DD_OK
},
8469 {WHITENESS
, "WHITENESS", DD_OK
},
8470 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
8473 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8474 0, 0, 640, 480, 0, 0, 0, 0);
8475 ddraw
= create_ddraw();
8476 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8477 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8479 skip("Failed to create a 3D device, skipping test.\n");
8480 DestroyWindow(window
);
8481 IDirectDraw2_Release(ddraw
);
8485 hr
= IDirectDraw2_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
8486 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
8487 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
8488 num_fourcc_codes
* sizeof(*fourcc_codes
));
8491 hr
= IDirectDraw2_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
8492 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
8493 for (i
= 0; i
< num_fourcc_codes
; i
++)
8495 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
8496 support_yuy2
= TRUE
;
8497 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
8498 support_uyvy
= TRUE
;
8500 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
8502 memset(&hal_caps
, 0, sizeof(hal_caps
));
8503 hal_caps
.dwSize
= sizeof(hal_caps
);
8504 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
8505 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
8507 if ((!support_yuy2
&& !support_uyvy
) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
8508 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
8510 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
8512 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
8513 memset(&fx
, 0, sizeof(fx
));
8514 fx
.dwSize
= sizeof(fx
);
8515 U5(fx
).dwFillColor
= 0xdeadbeef;
8517 memset(&surface_desc
, 0, sizeof(surface_desc
));
8518 surface_desc
.dwSize
= sizeof(surface_desc
);
8519 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8520 surface_desc
.dwWidth
= 64;
8521 surface_desc
.dwHeight
= 64;
8522 surface_desc
.ddpfPixelFormat
= tests
[i
].format
;
8523 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
8525 if (tests
[i
].caps
& DDSCAPS_TEXTURE
)
8527 struct format_support_check check
= {&tests
[i
].format
, FALSE
};
8528 hr
= IDirect3DDevice2_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
8529 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
8530 if (!check
.supported
)
8534 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !support_yuy2
)
8536 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !support_uyvy
)
8538 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
8541 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
8543 surface_desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
8544 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
8545 U2(surface_desc
).dwZBufferBitDepth
= get_device_z_depth(device
);
8548 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8549 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8551 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8552 todo_wine_if (tests
[i
].format
.dwFourCC
)
8553 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
8554 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
8556 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8557 todo_wine_if (tests
[i
].format
.dwFourCC
)
8558 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
8559 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
8561 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
8563 memset(&surface_desc
, 0, sizeof(surface_desc
));
8564 surface_desc
.dwSize
= sizeof(surface_desc
);
8565 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
8566 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8567 color
= surface_desc
.lpSurface
;
8568 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
8569 *color
, tests
[i
].result
, tests
[i
].name
);
8570 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8571 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8574 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8575 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
8576 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
8577 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8578 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
8579 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
8581 U5(fx
).dwFillColor
= 0xdeadbeef;
8582 fx
.dwROP
= BLACKNESS
;
8583 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
8584 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
8585 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
8586 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
8587 U5(fx
).dwFillColor
, tests
[i
].name
);
8589 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
8591 memset(&surface_desc
, 0, sizeof(surface_desc
));
8592 surface_desc
.dwSize
= sizeof(surface_desc
);
8593 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
8594 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8595 color
= surface_desc
.lpSurface
;
8596 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
8597 *color
, tests
[i
].name
);
8598 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8599 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8602 fx
.dwROP
= WHITENESS
;
8603 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
8604 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
8605 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
8606 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
8607 U5(fx
).dwFillColor
, tests
[i
].name
);
8609 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
8611 memset(&surface_desc
, 0, sizeof(surface_desc
));
8612 surface_desc
.dwSize
= sizeof(surface_desc
);
8613 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
8614 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8615 color
= surface_desc
.lpSurface
;
8616 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
8617 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
8618 *color
, tests
[i
].name
);
8619 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8620 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8623 IDirectDrawSurface_Release(surface
);
8626 memset(&fx
, 0, sizeof(fx
));
8627 fx
.dwSize
= sizeof(fx
);
8628 U5(fx
).dwFillColor
= 0xdeadbeef;
8629 fx
.dwROP
= WHITENESS
;
8631 memset(&surface_desc
, 0, sizeof(surface_desc
));
8632 surface_desc
.dwSize
= sizeof(surface_desc
);
8633 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8634 surface_desc
.dwWidth
= 64;
8635 surface_desc
.dwHeight
= 64;
8636 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
8637 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8638 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8639 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8640 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8641 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8642 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
8643 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8644 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8645 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
8646 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8649 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
8650 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8651 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
8652 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8654 /* Unused source rectangle. */
8655 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8656 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
8657 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
8658 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
8660 /* Unused source surface. */
8661 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8662 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8663 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
8664 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
8665 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8666 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8667 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
8668 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
8670 /* Inverted destination or source rectangle. */
8671 SetRect(&rect
, 5, 7, 7, 5);
8672 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8673 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
8674 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8675 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
8676 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8677 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8678 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8679 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8680 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
8681 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
8683 /* Negative rectangle. */
8684 SetRect(&rect
, -1, -1, 5, 5);
8685 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8686 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
8687 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8688 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
8689 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8690 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8691 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8692 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8693 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
8694 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
8696 /* Out of bounds rectangle. */
8697 SetRect(&rect
, 0, 0, 65, 65);
8698 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8699 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
8700 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
8701 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
8703 /* Combine multiple flags. */
8704 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8705 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
8706 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
8707 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8708 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
8709 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8711 for (i
= 0; i
< sizeof(rops
) / sizeof(*rops
); i
++)
8713 fx
.dwROP
= rops
[i
].rop
;
8714 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
8715 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#x for rop %s.\n", hr
, rops
[i
].name
);
8718 IDirectDrawSurface_Release(surface2
);
8719 IDirectDrawSurface_Release(surface
);
8721 memset(&surface_desc
, 0, sizeof(surface_desc
));
8722 surface_desc
.dwSize
= sizeof(surface_desc
);
8723 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_ZBUFFERBITDEPTH
;
8724 surface_desc
.dwWidth
= 64;
8725 surface_desc
.dwHeight
= 64;
8726 U2(surface_desc
).dwZBufferBitDepth
= get_device_z_depth(device
);
8727 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
8728 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8729 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8730 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
8731 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8734 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
8735 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8737 /* Unused source rectangle. */
8738 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8739 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
8741 /* Unused source surface. */
8742 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8743 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8744 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8745 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8747 /* Inverted destination or source rectangle. */
8748 SetRect(&rect
, 5, 7, 7, 5);
8749 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8750 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
8751 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8752 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
8753 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8754 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8755 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8756 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8758 /* Negative rectangle. */
8759 SetRect(&rect
, -1, -1, 5, 5);
8760 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8761 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
8762 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8763 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
8764 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8765 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8766 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8767 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8769 /* Out of bounds rectangle. */
8770 SetRect(&rect
, 0, 0, 65, 65);
8771 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8772 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
8774 /* Combine multiple flags. */
8775 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8776 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8778 IDirectDrawSurface_Release(surface2
);
8779 IDirectDrawSurface_Release(surface
);
8782 IDirect3DDevice2_Release(device
);
8783 refcount
= IDirectDraw2_Release(ddraw
);
8784 ok(refcount
== 0, "Ddraw object not properly released, refcount %u.\n", refcount
);
8785 DestroyWindow(window
);
8788 static BOOL
ddraw_is_nvidia(IDirectDraw2
*ddraw
)
8790 IDirectDraw4
*ddraw4
;
8791 DDDEVICEIDENTIFIER identifier
;
8794 if (!strcmp(winetest_platform
, "wine"))
8797 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirectDraw4
, (void **)&ddraw4
);
8798 ok(SUCCEEDED(hr
), "Failed to get IDirectDraw4 interface, hr %#x.\n", hr
);
8799 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw4
, &identifier
, 0);
8800 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#x.\n", hr
);
8801 IDirectDraw4_Release(ddraw4
);
8802 return identifier
.dwVendorId
== 0x10de;
8805 static void test_colorkey_precision(void)
8807 static D3DLVERTEX quad
[] =
8809 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {0.0f
}, {0.0f
}},
8810 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {0.0f
}, {1.0f
}},
8811 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {1.0f
}, {0.0f
}},
8812 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {1.0f
}, {1.0f
}},
8814 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8815 IDirect3DDevice2
*device
;
8816 IDirectDraw2
*ddraw
;
8817 IDirectDrawSurface
*rt
;
8818 IDirect3DViewport2
*viewport
;
8821 IDirectDrawSurface
*src
, *dst
, *texture
;
8822 D3DTEXTUREHANDLE handle
;
8823 IDirect3DTexture2
*d3d_texture
;
8824 IDirect3DMaterial2
*green
;
8825 DDSURFACEDESC surface_desc
, lock_desc
;
8831 DWORD data
[4] = {0}, color_mask
;
8832 BOOL is_nvidia
, is_warp
;
8835 unsigned int max
, shift
, bpp
, clear
;
8843 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
8845 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
8846 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
8851 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
8853 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
8854 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
8859 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
8861 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
8862 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
8867 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
8869 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
8870 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
8875 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8876 0, 0, 640, 480, 0, 0, 0, 0);
8877 ddraw
= create_ddraw();
8878 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8879 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8881 skip("Failed to create a 3D device, skipping test.\n");
8882 DestroyWindow(window
);
8883 IDirectDraw2_Release(ddraw
);
8886 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
8887 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
8889 is_nvidia
= ddraw_is_nvidia(ddraw
);
8890 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
8891 * (color key doesn't match although the values are equal), and a false
8892 * positive when the color key is 0 and the texture contains the value 1.
8893 * I don't want to mark this broken unconditionally since this would
8894 * essentially disable the test on Windows. Also on random occasions
8895 * 254 == 255 and 255 != 255.*/
8896 is_warp
= ddraw_is_warp(ddraw
);
8898 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
8899 viewport
= create_viewport(device
, 0, 0, 640, 480);
8900 viewport_set_background(device
, viewport
, green
);
8901 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
8902 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
8904 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
8905 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
8906 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
8907 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
8908 /* There's no way to ignore the texture color in d3d2, so multiply the texture color
8909 * with a black vertex color. */
8910 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATEALPHA
);
8911 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8913 memset(&fx
, 0, sizeof(fx
));
8914 fx
.dwSize
= sizeof(fx
);
8915 memset(&lock_desc
, 0, sizeof(lock_desc
));
8916 lock_desc
.dwSize
= sizeof(lock_desc
);
8918 for (t
= 0; t
< sizeof(tests
) / sizeof(*tests
); ++t
)
8920 if (is_nvidia
&& tests
[t
].skip_nv
)
8922 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
8926 memset(&surface_desc
, 0, sizeof(surface_desc
));
8927 surface_desc
.dwSize
= sizeof(surface_desc
);
8928 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8929 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8930 surface_desc
.dwWidth
= 4;
8931 surface_desc
.dwHeight
= 1;
8932 surface_desc
.ddpfPixelFormat
= tests
[t
].fmt
;
8933 /* Windows XP (at least with the r200 driver, other drivers untested) produces
8934 * garbage when doing color keyed texture->texture blits. */
8935 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
8936 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8937 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
8938 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8940 fx
.dwFillColor
= tests
[t
].clear
;
8941 /* On the w8 testbot (WARP driver) the blit result has different values in the
8943 color_mask
= U2(tests
[t
].fmt
).dwRBitMask
8944 | U3(tests
[t
].fmt
).dwGBitMask
8945 | U4(tests
[t
].fmt
).dwBBitMask
;
8947 for (c
= 0; c
<= tests
[t
].max
; ++c
)
8949 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
8950 * texture after it has been set once... */
8951 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
8952 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8953 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
8954 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
8955 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
8956 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8958 hr
= IDirectDrawSurface4_QueryInterface(texture
, &IID_IDirect3DTexture2
, (void **)&d3d_texture
);
8959 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
8960 hr
= IDirect3DTexture2_GetHandle(d3d_texture
, device
, &handle
);
8961 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
8962 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, handle
);
8963 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
8964 IDirect3DTexture2_Release(d3d_texture
);
8966 hr
= IDirectDrawSurface_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8967 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
8969 hr
= IDirectDrawSurface_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
8970 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
8971 switch (tests
[t
].bpp
)
8974 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
8975 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
8976 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
8977 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
8981 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
8982 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
8983 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
8984 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
8987 hr
= IDirectDrawSurface_Unlock(src
, 0);
8988 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
8989 hr
= IDirectDrawSurface_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
8990 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
8992 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
8993 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
8994 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
8995 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
8997 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
8998 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
9000 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
9001 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
9002 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
9003 switch (tests
[t
].bpp
)
9006 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
9007 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
9008 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
9009 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
9013 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
9014 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
9015 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
9016 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
9019 hr
= IDirectDrawSurface_Unlock(dst
, 0);
9020 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
9024 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9025 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
9027 if (data
[3] == tests
[t
].clear
)
9029 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
9030 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
9031 * even when a different surface is used. The blit itself doesn't draw anything,
9032 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
9033 * never be masked out by the key.
9035 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
9036 * test is disabled entirely.
9038 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
9039 * terrible on WARP. */
9040 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
9041 IDirectDrawSurface_Release(texture
);
9042 IDirectDrawSurface_Release(src
);
9043 IDirectDrawSurface_Release(dst
);
9048 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9049 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
9051 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9052 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
9054 if (c
== tests
[t
].max
)
9055 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9056 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
9058 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9059 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
9061 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9062 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
9064 hr
= IDirect3DDevice2_BeginScene(device
);
9065 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9066 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
9067 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9068 hr
= IDirect3DDevice2_EndScene(device
);
9069 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9071 color
= get_surface_color(rt
, 80, 240);
9073 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
9074 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9075 color
, tests
[t
].name
, c
);
9077 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
9078 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9079 color
, tests
[t
].name
, c
);
9081 color
= get_surface_color(rt
, 240, 240);
9082 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
9083 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9084 color
, tests
[t
].name
, c
);
9086 color
= get_surface_color(rt
, 400, 240);
9087 if (c
== tests
[t
].max
)
9088 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
9089 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9090 color
, tests
[t
].name
, c
);
9092 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
9093 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9094 color
, tests
[t
].name
, c
);
9096 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
9097 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
9098 IDirectDrawSurface_Release(texture
);
9100 IDirectDrawSurface_Release(src
);
9101 IDirectDrawSurface_Release(dst
);
9105 destroy_viewport(device
, viewport
);
9106 destroy_material(green
);
9107 IDirectDrawSurface_Release(rt
);
9108 IDirect3DDevice2_Release(device
);
9109 refcount
= IDirectDraw2_Release(ddraw
);
9110 ok(refcount
== 0, "Ddraw object not properly released, refcount %u.\n", refcount
);
9111 DestroyWindow(window
);
9114 static void test_range_colorkey(void)
9116 IDirectDraw2
*ddraw
;
9119 IDirectDrawSurface
*surface
;
9120 DDSURFACEDESC surface_desc
;
9124 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9125 0, 0, 640, 480, 0, 0, 0, 0);
9126 ddraw
= create_ddraw();
9127 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9128 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9129 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9131 memset(&surface_desc
, 0, sizeof(surface_desc
));
9132 surface_desc
.dwSize
= sizeof(surface_desc
);
9133 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
9134 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9135 surface_desc
.dwWidth
= 1;
9136 surface_desc
.dwHeight
= 1;
9137 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9138 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9139 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9140 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9141 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9142 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00000000;
9144 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
9145 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
9146 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
9147 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9148 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9150 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
9151 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
9152 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9153 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9155 /* Same for DDSCAPS_OFFSCREENPLAIN. */
9156 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9157 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
9158 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
9159 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9160 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9162 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
9163 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
9164 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9165 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9167 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
9168 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
9169 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9170 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9172 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
9173 ckey
.dwColorSpaceLowValue
= 0x00000000;
9174 ckey
.dwColorSpaceHighValue
= 0x00000001;
9175 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9176 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
9178 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9179 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
9180 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
9181 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
9183 ckey
.dwColorSpaceLowValue
= 0x00000001;
9184 ckey
.dwColorSpaceHighValue
= 0x00000000;
9185 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9186 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
9188 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9189 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
9190 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
9191 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
9193 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
9194 ckey
.dwColorSpaceLowValue
= 0x00000000;
9195 ckey
.dwColorSpaceHighValue
= 0x00000000;
9196 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9197 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
9199 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
9200 ckey
.dwColorSpaceLowValue
= 0x00000001;
9201 ckey
.dwColorSpaceHighValue
= 0x00000000;
9202 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9203 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9204 ckey
.dwColorSpaceLowValue
= 0x00000000;
9205 ckey
.dwColorSpaceHighValue
= 0x00000001;
9206 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9207 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9208 /* Range destination keys don't work either. */
9209 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
9210 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9212 /* Just to show it's not because of A, R, and G having equal values. */
9213 ckey
.dwColorSpaceLowValue
= 0x00000000;
9214 ckey
.dwColorSpaceHighValue
= 0x01010101;
9215 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9216 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9218 /* None of these operations modified the key. */
9219 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9220 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
9221 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
9222 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
9224 IDirectDrawSurface_Release(surface
),
9225 refcount
= IDirectDraw2_Release(ddraw
);
9226 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9227 DestroyWindow(window
);
9230 static void test_shademode(void)
9232 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9233 IDirect3DMaterial2
*background
;
9234 IDirect3DViewport2
*viewport
;
9235 IDirect3DDevice2
*device
;
9236 IDirectDrawSurface
*rt
;
9237 DWORD color0
, color1
;
9238 IDirectDraw2
*ddraw
;
9244 static D3DLVERTEX quad_strip
[] =
9246 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
9247 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
9248 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
9249 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
9253 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
9254 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
9255 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
9257 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
9258 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
9259 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
9265 DWORD color0
, color1
;
9269 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
9270 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
9271 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
9272 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
9273 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
9274 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
9277 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9278 0, 0, 640, 480, 0, 0, 0, 0);
9279 ddraw
= create_ddraw();
9280 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9281 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9283 skip("Failed to create a 3D device, skipping test.\n");
9284 IDirectDraw2_Release(ddraw
);
9285 DestroyWindow(window
);
9289 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
9290 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
9292 background
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
9293 viewport
= create_viewport(device
, 0, 0, 640, 480);
9294 viewport_set_background(device
, viewport
, background
);
9295 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
9296 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
9298 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
9299 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
9301 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
9302 * the color fixups we have to do for FLAT shading will be dependent on that. */
9304 for (i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); ++i
)
9306 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9307 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
9309 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
9310 ok(hr
== D3D_OK
, "Failed to set shade mode, hr %#x.\n", hr
);
9312 hr
= IDirect3DDevice2_BeginScene(device
);
9313 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9314 quad
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? quad_strip
: quad_list
;
9315 count
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? 4 : 6;
9316 hr
= IDirect3DDevice2_DrawPrimitive(device
, tests
[i
].primtype
, D3DVT_LVERTEX
, quad
, count
, 0);
9317 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9318 hr
= IDirect3DDevice2_EndScene(device
);
9319 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9321 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
9322 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
9324 /* For D3DSHADE_FLAT it should take the color of the first vertex of
9325 * each triangle. This requires EXT_provoking_vertex or similar
9326 * functionality being available. */
9327 /* PHONG should be the same as GOURAUD, since no hardware implements
9329 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
9330 i
, color0
, tests
[i
].color0
);
9331 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
9332 i
, color1
, tests
[i
].color1
);
9335 destroy_viewport(device
, viewport
);
9336 destroy_material(background
);
9337 IDirectDrawSurface_Release(rt
);
9338 refcount
= IDirect3DDevice2_Release(device
);
9339 ok(!refcount
, "Device has %u references left.\n", refcount
);
9340 IDirectDraw_Release(ddraw
);
9341 DestroyWindow(window
);
9344 static void test_lockrect_invalid(void)
9347 IDirectDraw2
*ddraw
;
9348 IDirectDrawSurface
*surface1
;
9349 IDirectDrawSurface2
*surface
;
9352 DDSURFACEDESC surface_desc
;
9354 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
9355 static RECT valid
[] =
9363 static RECT invalid
[] =
9365 {68, 60, 60, 68}, /* left > right */
9366 {60, 68, 68, 60}, /* top > bottom */
9367 {-8, 60, 0, 68}, /* left < surface */
9368 {60, -8, 68, 0}, /* top < surface */
9369 {-16, 60, -8, 68}, /* right < surface */
9370 {60, -16, 68, -8}, /* bottom < surface */
9371 {60, 60, 136, 68}, /* right > surface */
9372 {60, 60, 68, 136}, /* bottom > surface */
9373 {136, 60, 144, 68}, /* left > surface */
9374 {60, 136, 68, 144}, /* top > surface */
9384 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, "sysmem offscreenplain", DDERR_INVALIDPARAMS
},
9385 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, "vidmem offscreenplain", DDERR_INVALIDPARAMS
},
9386 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "sysmem texture", DDERR_INVALIDPARAMS
},
9387 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "vidmem texture", DDERR_INVALIDPARAMS
},
9390 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9391 0, 0, 640, 480, 0, 0, 0, 0);
9392 ddraw
= create_ddraw();
9393 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9394 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9395 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9397 memset(&hal_caps
, 0, sizeof(hal_caps
));
9398 hal_caps
.dwSize
= sizeof(hal_caps
);
9399 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
9400 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
9401 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
9403 skip("Required surface types not supported, skipping test.\n");
9407 for (r
= 0; r
< sizeof(resources
) / sizeof(*resources
); ++r
)
9409 memset(&surface_desc
, 0, sizeof(surface_desc
));
9410 surface_desc
.dwSize
= sizeof(surface_desc
);
9411 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9412 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
9413 surface_desc
.dwWidth
= 128;
9414 surface_desc
.dwHeight
= 128;
9415 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
9416 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9417 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9418 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xff0000;
9419 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x00ff00;
9420 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x0000ff;
9422 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
9423 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
9424 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
9425 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface2 interface, hr %#x.\n", hr
);
9426 IDirectDrawSurface_Release(surface1
);
9428 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, NULL
, DDLOCK_WAIT
, NULL
);
9429 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, resources
[r
].name
);
9431 for (i
= 0; i
< sizeof(valid
) / sizeof(*valid
); ++i
)
9433 RECT
*rect
= &valid
[i
];
9435 memset(&surface_desc
, 0, sizeof(surface_desc
));
9436 surface_desc
.dwSize
= sizeof(surface_desc
);
9438 hr
= IDirectDrawSurface2_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9439 ok(SUCCEEDED(hr
), "Lock failed (%#x) for rect %s, type %s.\n",
9440 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
9442 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
9443 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
9446 for (i
= 0; i
< sizeof(invalid
) / sizeof(*invalid
); ++i
)
9448 RECT
*rect
= &invalid
[i
];
9450 memset(&surface_desc
, 1, sizeof(surface_desc
));
9451 surface_desc
.dwSize
= sizeof(surface_desc
);
9453 hr
= IDirectDrawSurface2_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9454 ok(hr
== resources
[r
].hr
, "Lock returned %#x for rect %s, type %s.\n",
9455 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
9458 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
9459 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
9462 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9465 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9466 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#x, type %s.\n",
9467 hr
, resources
[r
].name
);
9468 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9469 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#x, type %s.\n",
9470 hr
, resources
[r
].name
);
9471 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
9472 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
9474 hr
= IDirectDrawSurface2_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
9475 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#x).\n", wine_dbgstr_rect(&valid
[0]), hr
);
9476 hr
= IDirectDrawSurface2_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
9477 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#x).\n",
9478 wine_dbgstr_rect(&valid
[0]), hr
);
9480 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
9481 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
9483 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
9484 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
9486 IDirectDrawSurface2_Release(surface
);
9490 IDirectDraw2_Release(ddraw
);
9491 DestroyWindow(window
);
9494 static void test_yv12_overlay(void)
9496 IDirectDrawSurface
*src_surface
, *dst_surface
;
9497 RECT rect
= {13, 17, 14, 18};
9498 unsigned int offset
, y
;
9499 unsigned char *base
;
9500 IDirectDraw2
*ddraw
;
9505 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9506 0, 0, 640, 480, 0, 0, 0, 0);
9507 ddraw
= create_ddraw();
9508 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9509 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9510 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9512 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
9514 skip("Failed to create a YV12 overlay, skipping test.\n");
9518 memset(&desc
, 0, sizeof(desc
));
9519 desc
.dwSize
= sizeof(desc
);
9520 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
9521 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
9523 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
9524 "Got unexpected flags %#x.\n", desc
.dwFlags
);
9525 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
9526 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
9527 "Got unexpected caps %#x.\n", desc
.ddsCaps
.dwCaps
);
9528 ok(desc
.dwWidth
== 256, "Got unexpected width %u.\n", desc
.dwWidth
);
9529 ok(desc
.dwHeight
== 256, "Got unexpected height %u.\n", desc
.dwHeight
);
9530 /* The overlay pitch seems to have 256 byte alignment. */
9531 ok(!(U1(desc
).lPitch
& 0xff), "Got unexpected pitch %u.\n", U1(desc
).lPitch
);
9533 /* Fill the surface with some data for the blit test. */
9534 base
= desc
.lpSurface
;
9536 for (y
= 0; y
< desc
.dwHeight
; ++y
)
9538 memset(base
+ U1(desc
).lPitch
* y
, 0x10, desc
.dwWidth
);
9541 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
9543 memset(base
+ U1(desc
).lPitch
* y
, 0x20, desc
.dwWidth
);
9546 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
9548 memset(base
+ U1(desc
).lPitch
* y
, 0x30, desc
.dwWidth
);
9551 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
9552 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
9554 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
9555 * other block-based formats like DXT the entire Y channel is stored in
9556 * one big chunk of memory, followed by the chroma channels. So partial
9557 * locks do not really make sense. Show that they are allowed nevertheless
9558 * and the offset points into the luminance data. */
9559 hr
= IDirectDrawSurface_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
9560 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
9561 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
9562 ok(offset
== rect
.top
* U1(desc
).lPitch
+ rect
.left
, "Got unexpected offset %u, expected %u.\n",
9563 offset
, rect
.top
* U1(desc
).lPitch
+ rect
.left
);
9564 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
9565 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
9567 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
9569 /* Windows XP with a Radeon X1600 GPU refuses to create a second
9570 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
9571 skip("Failed to create a second YV12 surface, skipping blit test.\n");
9572 IDirectDrawSurface_Release(src_surface
);
9576 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
9577 /* VMware rejects YV12 blits. This behavior has not been seen on real
9578 * hardware yet, so mark it broken. */
9579 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#x.\n", hr
);
9583 memset(&desc
, 0, sizeof(desc
));
9584 desc
.dwSize
= sizeof(desc
);
9585 hr
= IDirectDrawSurface_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
9586 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
9588 base
= desc
.lpSurface
;
9589 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
9590 base
+= desc
.dwHeight
* U1(desc
).lPitch
;
9591 todo_wine
ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
9592 base
+= desc
.dwHeight
/ 4 * U1(desc
).lPitch
;
9593 todo_wine
ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
9595 hr
= IDirectDrawSurface_Unlock(dst_surface
, NULL
);
9596 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
9599 IDirectDrawSurface_Release(dst_surface
);
9600 IDirectDrawSurface_Release(src_surface
);
9602 IDirectDraw2_Release(ddraw
);
9603 DestroyWindow(window
);
9606 static BOOL
dwm_enabled(void)
9610 if (!strcmp(winetest_platform
, "wine"))
9612 if (!pDwmIsCompositionEnabled
)
9614 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
9619 static void test_offscreen_overlay(void)
9621 IDirectDrawSurface
*overlay
, *offscreen
, *primary
;
9622 DDSURFACEDESC surface_desc
;
9623 IDirectDraw2
*ddraw
;
9628 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9629 0, 0, 640, 480, 0, 0, 0, 0);
9630 ddraw
= create_ddraw();
9631 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9632 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9633 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9635 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
9637 skip("Failed to create a UYVY overlay, skipping test.\n");
9641 memset(&surface_desc
, 0, sizeof(surface_desc
));
9642 surface_desc
.dwSize
= sizeof(surface_desc
);
9643 surface_desc
.dwFlags
= DDSD_CAPS
;
9644 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
9645 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
9646 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
9648 /* On Windows 7, and probably Vista, UpdateOverlay() will return
9649 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
9650 * surface prevents this by disabling the dwm. */
9651 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
9652 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9653 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
9654 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9656 /* Try to overlay a NULL surface. */
9657 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
9658 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9659 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
9660 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9662 /* Try to overlay an offscreen surface. */
9663 memset(&surface_desc
, 0, sizeof(surface_desc
));
9664 surface_desc
.dwSize
= sizeof(surface_desc
);
9665 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9666 surface_desc
.dwWidth
= 64;
9667 surface_desc
.dwHeight
= 64;
9668 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9669 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
9670 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9671 surface_desc
.ddpfPixelFormat
.dwFourCC
= 0;
9672 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
9673 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
9674 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
9675 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
9676 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
9677 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
9679 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
9680 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled()),
9681 "Failed to update overlay, hr %#x.\n", hr
);
9683 /* Try to overlay the primary with a non-overlay surface. */
9684 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
9685 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
9686 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
9687 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
9689 IDirectDrawSurface_Release(offscreen
);
9690 IDirectDrawSurface_Release(primary
);
9691 IDirectDrawSurface_Release(overlay
);
9693 IDirectDraw2_Release(ddraw
);
9694 DestroyWindow(window
);
9697 static void test_overlay_rect(void)
9699 IDirectDrawSurface
*overlay
, *primary
= NULL
;
9700 DDSURFACEDESC surface_desc
;
9701 RECT rect
= {0, 0, 64, 64};
9702 IDirectDraw2
*ddraw
;
9708 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9709 0, 0, 640, 480, 0, 0, 0, 0);
9710 ddraw
= create_ddraw();
9711 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9712 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9713 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9715 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
9717 skip("Failed to create a UYVY overlay, skipping test.\n");
9721 memset(&surface_desc
, 0, sizeof(surface_desc
));
9722 surface_desc
.dwSize
= sizeof(surface_desc
);
9723 surface_desc
.dwFlags
= DDSD_CAPS
;
9724 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
9725 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
9726 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
9728 /* On Windows 7, and probably Vista, UpdateOverlay() will return
9729 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
9730 * surface prevents this by disabling the dwm. */
9731 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
9732 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9733 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
9734 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9736 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
9739 win_skip("Cannot disable DWM, skipping overlay test.\n");
9743 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
9744 * used. This is not true in Windows Vista and earlier, but changed in
9746 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
9747 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
9748 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
9749 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
9750 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
9751 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9753 /* Show that the overlay position is the (top, left) coordinate of the
9754 * destination rectangle. */
9755 OffsetRect(&rect
, 32, 16);
9756 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
9757 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
9758 pos_x
= -1; pos_y
= -1;
9759 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
9760 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
9761 ok(pos_x
== rect
.left
, "Got unexpected pos_x %d, expected %d.\n", pos_x
, rect
.left
);
9762 ok(pos_y
== rect
.top
, "Got unexpected pos_y %d, expected %d.\n", pos_y
, rect
.top
);
9764 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
9765 * seen that the overlay overlays the whole primary(==screen). */
9766 hr2
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
9767 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#x.\n", hr2
);
9768 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
9769 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
9772 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
9773 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
9777 ok(pos_x
== 32, "Got unexpected pos_x %d.\n", pos_x
);
9778 ok(pos_y
== 16, "Got unexpected pos_y %d.\n", pos_y
);
9781 /* The position cannot be retrieved when the overlay is not shown. */
9782 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
9783 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
9784 pos_x
= -1; pos_y
= -1;
9785 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
9786 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#x.\n", hr
);
9787 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
9788 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
9790 IDirectDrawSurface_Release(overlay
);
9793 IDirectDrawSurface_Release(primary
);
9794 IDirectDraw2_Release(ddraw
);
9795 DestroyWindow(window
);
9798 static void test_blt(void)
9800 IDirectDrawSurface
*surface
, *rt
;
9801 DDSURFACEDESC surface_desc
;
9802 IDirect3DDevice2
*device
;
9803 IDirectDraw2
*ddraw
;
9817 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
9818 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
9819 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
9820 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
9821 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
9822 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
9823 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
9824 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
9825 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
9826 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
9829 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9830 0, 0, 640, 480, 0, 0, 0, 0);
9831 ddraw
= create_ddraw();
9832 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9833 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9835 skip("Failed to create a 3D device, skipping test.\n");
9836 IDirectDraw2_Release(ddraw
);
9837 DestroyWindow(window
);
9841 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
9842 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
9844 memset(&surface_desc
, 0, sizeof(surface_desc
));
9845 surface_desc
.dwSize
= sizeof(surface_desc
);
9846 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
9847 surface_desc
.dwWidth
= 640;
9848 surface_desc
.dwHeight
= 480;
9849 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9850 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9851 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9853 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
9854 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
9856 hr
= IDirectDrawSurface_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
9857 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
9859 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
9861 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
9862 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
9863 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
9865 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
9866 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
9867 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
9870 IDirectDrawSurface_Release(surface
);
9871 IDirectDrawSurface_Release(rt
);
9872 refcount
= IDirect3DDevice2_Release(device
);
9873 ok(!refcount
, "Device has %u references left.\n", refcount
);
9874 IDirectDraw2_Release(ddraw
);
9875 DestroyWindow(window
);
9878 static void test_getdc(void)
9880 IDirectDrawSurface
*surface
, *surface2
, *tmp
;
9881 DDSURFACEDESC surface_desc
, map_desc
;
9882 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
9883 IDirectDraw2
*ddraw
;
9892 DDPIXELFORMAT format
;
9893 BOOL getdc_supported
;
9898 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
9899 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
9900 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
9901 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
9902 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
9903 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
9904 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
9905 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
9906 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
9907 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
9908 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
9909 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
9910 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
9911 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
9912 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
9913 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
9914 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
9915 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
9916 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
9917 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
9918 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
9919 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
9920 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
9921 * This is not implemented in wine yet, so disable the test for now.
9922 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
9923 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
9924 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
9926 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
9927 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
9928 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
9929 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
9930 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
9931 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
9932 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
9933 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
9934 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
9935 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
9936 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
9937 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
9938 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
9939 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
9942 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9943 0, 0, 640, 480, 0, 0, 0, 0);
9944 ddraw
= create_ddraw();
9945 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9946 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9947 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9949 for (i
= 0; i
< (sizeof(test_data
) / sizeof(*test_data
)); ++i
)
9951 memset(&surface_desc
, 0, sizeof(surface_desc
));
9952 surface_desc
.dwSize
= sizeof(surface_desc
);
9953 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9954 surface_desc
.dwWidth
= 64;
9955 surface_desc
.dwHeight
= 64;
9956 U4(surface_desc
).ddpfPixelFormat
= test_data
[i
].format
;
9957 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9959 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
9961 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9962 if (FAILED(hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
9964 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", test_data
[i
].name
, hr
);
9969 dc
= (void *)0x1234;
9970 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
9971 if (test_data
[i
].getdc_supported
)
9972 ok(SUCCEEDED(hr
) || (test_data
[i
].alt_result
&& hr
== test_data
[i
].alt_result
),
9973 "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
9975 ok(FAILED(hr
), "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
9979 unsigned int width_bytes
;
9985 type
= GetObjectType(dc
);
9986 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
9987 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
9988 type
= GetObjectType(bitmap
);
9989 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
9991 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
9992 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
9993 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
9994 dib
.dsBm
.bmType
, test_data
[i
].name
);
9995 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
9996 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
9997 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
9998 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
9999 width_bytes
= ((dib
.dsBm
.bmWidth
* U1(test_data
[i
].format
).dwRGBBitCount
+ 31) >> 3) & ~3;
10000 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
10001 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
10002 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
10003 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
10004 ok(dib
.dsBm
.bmBitsPixel
== U1(test_data
[i
].format
).dwRGBBitCount
,
10005 "Got unexpected bit count %d for format %s.\n",
10006 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
10007 ok(!!dib
.dsBm
.bmBits
, "Got unexpected bits %p for format %s.\n",
10008 dib
.dsBm
.bmBits
, test_data
[i
].name
);
10010 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %u for format %s.\n",
10011 dib
.dsBmih
.biSize
, test_data
[i
].name
);
10012 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
10013 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
10014 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
10015 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
10016 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
10017 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
10018 ok(dib
.dsBmih
.biBitCount
== U1(test_data
[i
].format
).dwRGBBitCount
,
10019 "Got unexpected bit count %u for format %s.\n",
10020 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
10021 ok(dib
.dsBmih
.biCompression
== (U1(test_data
[i
].format
).dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
10022 || broken(U2(test_data
[i
].format
).dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
10023 "Got unexpected compression %#x for format %s.\n",
10024 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
10025 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %u for format %s.\n",
10026 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
10027 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %d for format %s.\n",
10028 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
10029 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %d for format %s.\n",
10030 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
10031 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %u for format %s.\n",
10032 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
10033 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %u for format %s.\n",
10034 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
10036 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
10038 ok((dib
.dsBitfields
[0] == U2(test_data
[i
].format
).dwRBitMask
10039 && dib
.dsBitfields
[1] == U3(test_data
[i
].format
).dwGBitMask
10040 && dib
.dsBitfields
[2] == U4(test_data
[i
].format
).dwBBitMask
)
10041 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
10042 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
10043 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
10047 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
10048 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
10049 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
10051 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
10052 ok(!dib
.dsOffset
, "Got unexpected offset %u for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
10054 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10055 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10059 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
10062 IDirectDrawSurface_Release(surface
);
10067 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
10068 if (FAILED(hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
10070 skip("Failed to create mip-mapped texture for format %s (hr %#x), skipping tests.\n",
10071 test_data
[i
].name
, hr
);
10075 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
10076 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10077 hr
= IDirectDrawSurface_GetAttachedSurface(tmp
, &caps
, &surface2
);
10078 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10079 IDirectDrawSurface_Release(tmp
);
10081 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10082 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10083 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10084 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10085 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
10086 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10087 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
10088 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10090 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10091 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10092 dc2
= (void *)0x1234;
10093 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
10094 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10095 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
10096 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10097 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10098 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10099 ok(hr
== DDERR_NODC
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10101 map_desc
.dwSize
= sizeof(map_desc
);
10102 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10103 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10104 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10105 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10106 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10107 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10108 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10109 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10111 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10112 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10113 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10114 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10115 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10116 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10118 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10119 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10120 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10121 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10122 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10123 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10124 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10125 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10127 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10128 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10129 hr
= IDirectDrawSurface_GetDC(surface2
, &dc2
);
10130 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10131 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc2
);
10132 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10133 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10134 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10136 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
10137 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10138 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
10139 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10140 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc2
);
10141 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10142 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
10143 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10145 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10146 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10147 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10148 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10149 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
10150 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10151 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10152 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10154 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10155 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10156 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10157 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10158 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10159 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10160 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10161 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10163 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10164 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10165 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10166 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10167 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10168 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10169 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
10170 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10172 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10173 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10174 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10175 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10176 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
10177 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10178 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10179 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10181 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
10182 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10183 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10184 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10185 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10186 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10187 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
10188 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10190 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10191 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10192 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
10193 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10194 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10195 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10196 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
10197 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10198 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10199 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10201 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
10202 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10203 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10204 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10205 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
10206 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10207 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10208 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10209 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
10210 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10212 IDirectDrawSurface_Release(surface2
);
10213 IDirectDrawSurface_Release(surface
);
10216 IDirectDraw2_Release(ddraw
);
10217 DestroyWindow(window
);
10220 static void test_draw_primitive(void)
10222 static WORD indices
[] = {0, 1, 2, 3};
10223 static D3DVERTEX quad
[] =
10225 {{-1.0f
}, {-1.0f
}, {0.0f
}},
10226 {{-1.0f
}, { 1.0f
}, {0.0f
}},
10227 {{ 1.0f
}, {-1.0f
}, {0.0f
}},
10228 {{ 1.0f
}, { 1.0f
}, {0.0f
}},
10230 IDirect3DViewport2
*viewport
;
10231 IDirect3DDevice2
*device
;
10232 IDirectDraw2
*ddraw
;
10238 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
10239 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
10240 ddraw
= create_ddraw();
10241 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10242 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10244 skip("Failed to create a 3D device, skipping test.\n");
10245 IDirectDraw2_Release(ddraw
);
10246 DestroyWindow(window
);
10250 viewport
= create_viewport(device
, 0, 0, 640, 480);
10251 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
10252 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
10254 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
10255 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
10257 IDirect3D2_Release(d3d
);
10259 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, NULL
, 0, 0);
10260 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10261 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, 0);
10262 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10264 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, indices
, 4, 0);
10265 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10267 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, NULL
, 0, 0);
10268 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10269 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
10270 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10271 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, indices
, 4, 0);
10272 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10274 destroy_viewport(device
, viewport
);
10275 refcount
= IDirect3DDevice2_Release(device
);
10276 ok(!refcount
, "Device has %u references left.\n", refcount
);
10277 IDirectDraw2_Release(ddraw
);
10278 DestroyWindow(window
);
10281 static void test_edge_antialiasing_blending(void)
10283 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10284 IDirect3DMaterial2
*green_background
;
10285 IDirect3DMaterial2
*red_background
;
10286 IDirectDrawSurface
*offscreen
, *ds
;
10287 D3DDEVICEDESC hal_desc
, hel_desc
;
10288 IDirect3DViewport2
*viewport
;
10289 DDSURFACEDESC surface_desc
;
10290 IDirect3DDevice2
*device
;
10291 IDirectDraw2
*ddraw
;
10297 static D3DMATRIX mat
=
10299 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10300 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10301 0.0f
, 0.0f
, 1.0f
, 0.0f
,
10302 0.0f
, 0.0f
, 0.0f
, 1.0f
,
10304 static D3DLVERTEX green_quad
[] =
10306 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
10307 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
10308 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
10309 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
10311 static D3DLVERTEX red_quad
[] =
10313 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xccff0000}},
10314 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xccff0000}},
10315 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xccff0000}},
10316 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xccff0000}},
10319 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
10320 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
10321 ddraw
= create_ddraw();
10322 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10323 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10325 skip("Failed to create a 3D device.\n");
10326 DestroyWindow(window
);
10330 memset(&hal_desc
, 0, sizeof(hal_desc
));
10331 hal_desc
.dwSize
= sizeof(hal_desc
);
10332 memset(&hel_desc
, 0, sizeof(hel_desc
));
10333 hel_desc
.dwSize
= sizeof(hel_desc
);
10334 hr
= IDirect3DDevice2_GetCaps(device
, &hal_desc
, &hel_desc
);
10335 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
10336 trace("HAL line edge antialiasing support: %#x.\n",
10337 hal_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
10338 trace("HAL triangle edge antialiasing support: %#x.\n",
10339 hal_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
10340 trace("HEL line edge antialiasing support: %#x.\n",
10341 hel_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
10342 trace("HEL triangle edge antialiasing support: %#x.\n",
10343 hel_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
10345 memset(&surface_desc
, 0, sizeof(surface_desc
));
10346 surface_desc
.dwSize
= sizeof(surface_desc
);
10347 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
10348 surface_desc
.dwWidth
= 640;
10349 surface_desc
.dwHeight
= 480;
10350 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
10351 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10352 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
10353 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
10354 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10355 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10356 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10357 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
10358 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
10359 ok(hr
== D3D_OK
, "Creating the offscreen render target failed, hr %#x.\n", hr
);
10361 ds
= get_depth_stencil(device
);
10362 hr
= IDirectDrawSurface_AddAttachedSurface(offscreen
, ds
);
10363 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
10364 IDirectDrawSurface_Release(ds
);
10366 hr
= IDirect3DDevice2_SetRenderTarget(device
, offscreen
, 0);
10367 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
10369 red_background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 0.8f
);
10370 green_background
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.5f
);
10372 viewport
= create_viewport(device
, 0, 0, 640, 480);
10373 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
10374 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
10376 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
10377 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
10378 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
10379 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
10380 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
10381 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
10382 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
10383 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
10384 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
10385 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
10386 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
10387 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
10388 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
10389 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#x.\n", hr
);
10390 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
10391 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
10392 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
10393 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
10395 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
10396 ok(SUCCEEDED(hr
), "Failed to enable blending, hr %#x.\n", hr
);
10397 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
10398 ok(SUCCEEDED(hr
), "Failed to set src blend, hr %#x.\n", hr
);
10399 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
10400 ok(SUCCEEDED(hr
), "Failed to set dest blend, hr %#x.\n", hr
);
10402 viewport_set_background(device
, viewport
, red_background
);
10403 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10404 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
10405 hr
= IDirect3DDevice2_BeginScene(device
);
10406 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10407 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
10408 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10409 hr
= IDirect3DDevice2_EndScene(device
);
10410 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10411 color
= get_surface_color(offscreen
, 320, 240);
10412 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
10414 viewport_set_background(device
, viewport
, green_background
);
10415 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10416 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
10417 hr
= IDirect3DDevice2_BeginScene(device
);
10418 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10419 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
10420 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10421 hr
= IDirect3DDevice2_EndScene(device
);
10422 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10423 color
= get_surface_color(offscreen
, 320, 240);
10424 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
10426 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
10427 ok(SUCCEEDED(hr
), "Failed to disable blending, hr %#x.\n", hr
);
10429 viewport_set_background(device
, viewport
, red_background
);
10430 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10431 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
10432 hr
= IDirect3DDevice2_BeginScene(device
);
10433 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10434 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
10435 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10436 hr
= IDirect3DDevice2_EndScene(device
);
10437 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10438 color
= get_surface_color(offscreen
, 320, 240);
10439 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
10441 viewport_set_background(device
, viewport
, green_background
);
10442 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10443 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
10444 hr
= IDirect3DDevice2_BeginScene(device
);
10445 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10446 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
10447 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10448 hr
= IDirect3DDevice2_EndScene(device
);
10449 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10450 color
= get_surface_color(offscreen
, 320, 240);
10451 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
10453 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_EDGEANTIALIAS
, TRUE
);
10454 ok(SUCCEEDED(hr
), "Failed to enable edge antialiasing, hr %#x.\n", hr
);
10456 viewport_set_background(device
, viewport
, red_background
);
10457 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10458 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
10459 hr
= IDirect3DDevice2_BeginScene(device
);
10460 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10461 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
10462 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10463 hr
= IDirect3DDevice2_EndScene(device
);
10464 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10465 color
= get_surface_color(offscreen
, 320, 240);
10466 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
10468 viewport_set_background(device
, viewport
, green_background
);
10469 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10470 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
10471 hr
= IDirect3DDevice2_BeginScene(device
);
10472 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10473 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
10474 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10475 hr
= IDirect3DDevice2_EndScene(device
);
10476 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10477 color
= get_surface_color(offscreen
, 320, 240);
10478 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
10480 IDirectDrawSurface_Release(offscreen
);
10481 destroy_viewport(device
, viewport
);
10482 destroy_material(red_background
);
10483 destroy_material(green_background
);
10484 refcount
= IDirect3DDevice2_Release(device
);
10485 ok(!refcount
, "Device has %u references left.\n", refcount
);
10486 IDirectDraw2_Release(ddraw
);
10487 DestroyWindow(window
);
10490 /* TransformVertices always writes 32 bytes regardless of the input / output stride.
10491 * The stride is honored for navigating to the next vertex. 3 floats input position
10492 * are read, and 16 bytes extra vertex data are copied around. */
10493 struct transform_input
10495 float x
, y
, z
, unused1
; /* Position data, transformed. */
10496 DWORD v1
, v2
, v3
, v4
; /* Extra data, e.g. color and texture coords, copied. */
10500 struct transform_output
10503 DWORD v1
, v2
, v3
, v4
;
10504 DWORD unused3
, unused4
;
10507 static void test_transform_vertices(void)
10509 IDirect3DDevice2
*device
;
10510 IDirectDrawSurface
*rt
;
10511 IDirectDraw2
*ddraw
;
10516 IDirect3DViewport2
*viewport
;
10517 IDirect3DMaterial2
*background
;
10518 static struct transform_input position_tests
[] =
10520 { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
10521 { 1.0f
, 1.0f
, 1.0f
, 8.0f
, 6, 7, 8, 9, 10},
10522 {-1.0f
, -1.0f
, -1.0f
, 4.0f
, 11, 12, 13, 14, 15},
10523 { 0.5f
, 0.5f
, 0.5f
, 2.0f
, 16, 17, 18, 19, 20},
10524 {-0.5f
, -0.5f
, -0.5f
, 1.0f
, ~1U, ~2U, ~3U, ~4U, ~5U},
10525 {-0.5f
, -0.5f
, 0.0f
, 0.0f
, ~6U, ~7U, ~8U, ~9U, ~0U},
10527 static struct transform_input cliptest
[] =
10529 { 25.59f
, 25.59f
, 1.0f
, 0.0f
, 1, 2, 3, 4, 5},
10530 { 25.61f
, 25.61f
, 1.01f
, 0.0f
, 1, 2, 3, 4, 5},
10531 {-25.59f
, -25.59f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
10532 {-25.61f
, -25.61f
, -0.01f
, 0.0f
, 1, 2, 3, 4, 5},
10534 static struct transform_input offscreentest
[] =
10536 {128.1f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
10538 struct transform_output out
[ARRAY_SIZE(position_tests
)];
10539 D3DHVERTEX out_h
[ARRAY_SIZE(position_tests
)];
10540 D3DTRANSFORMDATA transformdata
;
10541 static const D3DVIEWPORT vp_template
=
10543 sizeof(vp_template
), 0, 0, 256, 256, 5.0f
, 5.0f
, 256.0f
, 256.0f
, -25.0f
, 60.0f
10545 D3DVIEWPORT vp_data
=
10547 sizeof(vp_data
), 0, 0, 256, 256, 1.0f
, 1.0f
, 256.0f
, 256.0f
, 0.0f
, 1.0f
10551 static D3DMATRIX mat_scale
=
10553 2.0f
, 0.0f
, 0.0f
, 0.0f
,
10554 0.0f
, 2.0f
, 0.0f
, 0.0f
,
10555 0.0f
, 0.0f
, 2.0f
, 0.0f
,
10556 0.0f
, 0.0f
, 0.0f
, 1.0f
,
10560 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10561 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10562 0.0f
, 0.0f
, 1.0f
, 0.0f
,
10563 1.0f
, 0.0f
, 0.0f
, 1.0f
,
10567 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10568 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10569 0.0f
, 0.0f
, 1.0f
, 0.0f
,
10570 0.0f
, 1.0f
, 0.0f
, 1.0f
,
10572 static D3DLVERTEX quad
[] =
10574 {{-0.75f
},{-0.5f
}, {0.0f
}, 0, {0xffff0000}},
10575 {{-0.75f
},{ 0.25f
}, {0.0f
}, 0, {0xffff0000}},
10576 {{ 0.5f
}, {-0.5f
}, {0.0f
}, 0, {0xffff0000}},
10577 {{ 0.5f
}, { 0.25f
}, {0.0f
}, 0, {0xffff0000}},
10579 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10582 for (i
= 0; i
< ARRAY_SIZE(out
); ++i
)
10584 out
[i
].unused3
= 0xdeadbeef;
10585 out
[i
].unused4
= 0xcafecafe;
10588 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
10589 0, 0, 640, 480, 0, 0, 0, 0);
10590 ddraw
= create_ddraw();
10591 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10592 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10594 skip("Failed to create a 3D device, skipping test.\n");
10595 IDirectDraw2_Release(ddraw
);
10596 DestroyWindow(window
);
10599 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
10600 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10602 viewport
= create_viewport(device
, 0, 0, 256, 256);
10603 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
10604 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
10606 memset(&transformdata
, 0, sizeof(transformdata
));
10607 transformdata
.dwSize
= sizeof(transformdata
);
10608 transformdata
.lpIn
= position_tests
;
10609 transformdata
.dwInSize
= sizeof(position_tests
[0]);
10610 transformdata
.lpOut
= out
;
10611 transformdata
.dwOutSize
= sizeof(out
[0]);
10612 transformdata
.lpHOut
= NULL
;
10614 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
10615 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
10616 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10617 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
10619 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
10621 static const struct vec4 cmp
[] =
10623 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {129.0f
, 127.0f
, 1.0f
, 1.0f
}, {127.0f
, 129.0f
, -1.0f
, 1.0f
},
10624 {128.5f
, 127.5f
, 0.5f
, 1.0f
}, {127.5f
, 128.5f
, -0.5f
, 1.0f
}, {127.5f
, 128.5f
, 0.0f
, 1.0f
}
10627 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
10628 "Vertex %u differs. Got %f %f %f %f.\n", i
,
10629 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
10630 ok(out
[i
].v1
== position_tests
[i
].v1
&& out
[i
].v2
== position_tests
[i
].v2
10631 && out
[i
].v3
== position_tests
[i
].v3
&& out
[i
].v4
== position_tests
[i
].v4
,
10632 "Vertex %u payload is %u %u %u %u.\n", i
, out
[i
].v1
, out
[i
].v2
, out
[i
].v3
, out
[i
].v4
);
10633 ok(out
[i
].unused3
== 0xdeadbeef && out
[i
].unused4
== 0xcafecafe,
10634 "Vertex %u unused data is %#x, %#x.\n", i
, out
[i
].unused3
, out
[i
].unused4
);
10637 vp_data
= vp_template
;
10638 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
10639 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
10640 offscreen
= 0xdeadbeef;
10641 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
10642 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
10643 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10644 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
10646 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
10648 static const struct vec4 cmp
[] =
10650 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {133.0f
, 123.0f
, 1.0f
, 1.0f
}, {123.0f
, 133.0f
, -1.0f
, 1.0f
},
10651 {130.5f
, 125.5f
, 0.5f
, 1.0f
}, {125.5f
, 130.5f
, -0.5f
, 1.0f
}, {125.5f
, 130.5f
, 0.0f
, 1.0f
}
10653 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
10654 "Vertex %u differs. Got %f %f %f %f.\n", i
,
10655 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
10660 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
10661 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
10662 offscreen
= 0xdeadbeef;
10663 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
10664 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
10665 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10666 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
10667 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
10669 static const struct vec4 cmp
[] =
10671 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, {133.0f
, 153.0f
, -1.0f
, 1.0f
},
10672 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, {135.5f
, 150.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
10674 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
10675 "Vertex %u differs. Got %f %f %f %f.\n", i
,
10676 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
10679 transformdata
.lpHOut
= out_h
;
10680 offscreen
= 0xdeadbeef;
10681 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
10682 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10683 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10684 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
10685 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
10687 static const D3DHVERTEX cmp_h
[] =
10689 {0, { 0.0f
}, { 0.0f
}, { 0.0f
}}, {0, { 1.0f
}, { 1.0f
}, {1.0f
}},
10690 {D3DCLIP_FRONT
, {-1.0f
}, {-1.0f
}, {-1.0f
}}, {0, { 0.5f
}, { 0.5f
}, {0.5f
}},
10691 {D3DCLIP_FRONT
, {-0.5f
}, {-0.5f
}, {-0.5f
}}, {0, {-0.5f
}, {-0.5f
}, {0.0f
}}
10693 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
10694 && compare_float(U1(cmp_h
[i
]).hy
, U1(out_h
[i
]).hy
, 4096)
10695 && compare_float(U1(cmp_h
[i
]).hz
, U1(out_h
[i
]).hz
, 4096)
10696 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
10697 "HVertex %u differs. Got %#x %f %f %f.\n", i
,
10698 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
10700 /* No scheme has been found behind those return values. It seems to be
10701 * whatever data windows has when throwing the vertex away. Modify the
10702 * input test vertices to test this more. Depending on the input data
10703 * it can happen that the z coord gets written into y, or similar things. */
10706 static const struct vec4 cmp
[] =
10708 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, { -1.0f
, -1.0f
, 0.5f
, 1.0f
},
10709 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, { -0.5f
, -0.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
10711 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
10712 "Vertex %u differs. Got %f %f %f %f.\n", i
,
10713 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
10717 transformdata
.lpIn
= cliptest
;
10718 transformdata
.dwInSize
= sizeof(cliptest
[0]);
10719 offscreen
= 0xdeadbeef;
10720 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
10721 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10722 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10723 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
10724 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
10726 static const DWORD flags
[] =
10729 D3DCLIP_RIGHT
| D3DCLIP_BACK
| D3DCLIP_TOP
,
10731 D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,
10733 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
10736 vp_data
= vp_template
;
10737 vp_data
.dwWidth
= 10;
10738 vp_data
.dwHeight
= 480;
10739 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
10740 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
10741 offscreen
= 0xdeadbeef;
10742 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
10743 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10744 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10745 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
10746 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
10748 static const DWORD flags
[] =
10751 D3DCLIP_RIGHT
| D3DCLIP_BACK
,
10753 D3DCLIP_LEFT
| D3DCLIP_FRONT
,
10755 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
10758 vp_data
= vp_template
;
10759 vp_data
.dwWidth
= 256;
10760 vp_data
.dwHeight
= 256;
10761 vp_data
.dvScaleX
= 1;
10762 vp_data
.dvScaleY
= 1;
10763 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
10764 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
10765 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
10766 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10767 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10768 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
10769 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
10771 static const DWORD flags
[] =
10778 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
10781 /* Finally try to figure out how the DWORD dwOffscreen works.
10782 * It is a logical AND of the vertices' dwFlags members. */
10783 vp_data
= vp_template
;
10784 vp_data
.dwWidth
= 5;
10785 vp_data
.dwHeight
= 5;
10786 vp_data
.dvScaleX
= 10000.0f
;
10787 vp_data
.dvScaleY
= 10000.0f
;
10788 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
10789 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
10790 transformdata
.lpIn
= cliptest
;
10791 offscreen
= 0xdeadbeef;
10792 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
10793 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
10794 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10795 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
10797 offscreen
= 0xdeadbeef;
10798 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
10799 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10800 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10801 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
10802 offscreen
= 0xdeadbeef;
10803 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
10804 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10805 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10806 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
10807 hr
= IDirect3DViewport2_TransformVertices(viewport
, 3,
10808 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10809 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10810 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
10812 transformdata
.lpIn
= cliptest
+ 1;
10813 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
10814 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10815 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10816 ok(offscreen
== (D3DCLIP_BACK
| D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
10818 transformdata
.lpIn
= cliptest
+ 2;
10819 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
10820 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10821 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10822 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
10823 offscreen
= 0xdeadbeef;
10824 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
10825 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10826 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10827 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
10829 transformdata
.lpIn
= cliptest
+ 3;
10830 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
10831 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10832 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10833 ok(offscreen
== (D3DCLIP_FRONT
| D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
10835 transformdata
.lpIn
= offscreentest
;
10836 transformdata
.dwInSize
= sizeof(offscreentest
[0]);
10837 vp_data
= vp_template
;
10838 vp_data
.dwWidth
= 257;
10839 vp_data
.dwHeight
= 257;
10840 vp_data
.dvScaleX
= 1.0f
;
10841 vp_data
.dvScaleY
= 1.0f
;
10842 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
10843 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
10844 offscreen
= 0xdeadbeef;
10845 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
10846 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10847 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10848 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
10850 vp_data
.dwWidth
= 256;
10851 vp_data
.dwHeight
= 256;
10852 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
10853 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
10854 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
10855 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10856 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10857 ok(offscreen
== D3DCLIP_RIGHT
, "Offscreen is %x.\n", offscreen
);
10859 /* Test the effect of Matrices.
10861 * Basically the x coodinate ends up as ((x + 1) * 2 + 0) * 5 and
10862 * y as ((y + 0) * 2 + 1) * 5. The 5 comes from dvScaleX/Y, 2 from
10863 * the view matrix and the +1's from the world and projection matrix. */
10866 vp_data
.dwWidth
= 256;
10867 vp_data
.dwHeight
= 256;
10868 vp_data
.dvScaleX
= 5.0f
;
10869 vp_data
.dvScaleY
= 5.0f
;
10870 vp_data
.dvMinZ
= 0.0f
;
10871 vp_data
.dvMaxZ
= 1.0f
;
10872 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
10873 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
10875 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_translate1
);
10876 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
10877 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_scale
);
10878 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
10879 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_translate2
);
10880 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
10882 transformdata
.lpIn
= position_tests
;
10883 transformdata
.dwInSize
= sizeof(position_tests
[0]);
10884 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
10885 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
10886 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10888 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
10890 static const struct vec4 cmp
[] =
10892 {138.0f
, 123.0f
, 0.0f
, 1.0f
}, {148.0f
, 113.0f
, 2.0f
, 1.0f
}, {128.0f
, 133.0f
, -2.0f
, 1.0f
},
10893 {143.0f
, 118.0f
, 1.0f
, 1.0f
}, {133.0f
, 128.0f
, -1.0f
, 1.0f
}, {133.0f
, 128.0f
, 0.0f
, 1.0f
}
10896 todo_wine
ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
10897 "Vertex %u differs. Got %f %f %f %f.\n", i
,
10898 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
10901 /* Invalid flags. */
10902 offscreen
= 0xdeadbeef;
10903 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
10904 &transformdata
, 0, &offscreen
);
10905 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
10906 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
10908 /* NULL transform data. */
10909 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
10910 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
10911 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
10912 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
10913 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
10914 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
10915 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
10916 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
10918 /* NULL transform data and NULL dwOffscreen.
10920 * Valid transform data + NULL dwOffscreen -> crash. */
10921 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
10922 NULL
, D3DTRANSFORM_UNCLIPPED
, NULL
);
10923 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
10926 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
10927 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
10928 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10929 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
10930 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
10931 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10932 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10933 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
10935 /* Invalid sizes. */
10936 offscreen
= 0xdeadbeef;
10937 transformdata
.dwSize
= sizeof(transformdata
) - 1;
10938 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
10939 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
10940 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
10941 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
10942 transformdata
.dwSize
= sizeof(transformdata
) + 1;
10943 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
10944 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
10945 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
10946 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
10948 /* NULL lpIn or lpOut -> crash, except when transforming 0 vertices. */
10949 transformdata
.dwSize
= sizeof(transformdata
);
10950 transformdata
.lpIn
= NULL
;
10951 transformdata
.lpOut
= NULL
;
10952 offscreen
= 0xdeadbeef;
10953 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
10954 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
10955 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
10956 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
10958 /* Test how vertices are transformed during draws. */
10961 vp_data
.dwWidth
= 200;
10962 vp_data
.dwHeight
= 400;
10963 vp_data
.dvScaleX
= 20.0f
;
10964 vp_data
.dvScaleY
= 50.0f
;
10965 vp_data
.dvMinZ
= 0.0f
;
10966 vp_data
.dvMaxZ
= 1.0f
;
10967 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
10968 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
10969 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
10970 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
10972 ok(SUCCEEDED(hr
), "Failed to clear the render target, hr %#x.\n", hr
);
10973 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 0.0f
);
10974 viewport_set_background(device
, viewport
, background
);
10975 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10976 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
10978 hr
= IDirect3DDevice2_BeginScene(device
);
10979 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10980 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
10981 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10982 hr
= IDirect3DDevice2_EndScene(device
);
10983 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10985 color
= get_surface_color(rt
, 128, 143);
10986 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
10987 color
= get_surface_color(rt
, 132, 143);
10988 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
10989 color
= get_surface_color(rt
, 128, 147);
10990 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
10991 color
= get_surface_color(rt
, 132, 147);
10992 todo_wine
ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
10994 color
= get_surface_color(rt
, 177, 217);
10995 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
10996 color
= get_surface_color(rt
, 181, 217);
10997 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
10998 color
= get_surface_color(rt
, 177, 221);
10999 todo_wine
ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11000 color
= get_surface_color(rt
, 181, 221);
11001 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11003 IDirectDrawSurface_Release(rt
);
11004 destroy_viewport(device
, viewport
);
11005 IDirect3DMaterial2_Release(background
);
11006 refcount
= IDirect3DDevice_Release(device
);
11007 ok(!refcount
, "Device has %u references left.\n", refcount
);
11008 IDirectDraw2_Release(ddraw
);
11009 DestroyWindow(window
);
11014 IDirectDraw2
*ddraw
;
11015 DEVMODEW current_mode
;
11018 if (!(ddraw
= create_ddraw()))
11020 skip("Failed to create a ddraw object, skipping tests.\n");
11023 IDirectDraw2_Release(ddraw
);
11025 memset(¤t_mode
, 0, sizeof(current_mode
));
11026 current_mode
.dmSize
= sizeof(current_mode
);
11027 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
11028 registry_mode
.dmSize
= sizeof(registry_mode
);
11029 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
11030 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
11031 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
11033 skip("Current mode does not match registry mode, skipping test.\n");
11037 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
11038 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
11040 test_coop_level_create_device_window();
11041 test_clipper_blt();
11042 test_coop_level_d3d_state();
11043 test_surface_interface_mismatch();
11044 test_coop_level_threaded();
11046 test_texture_load_ckey();
11055 test_window_style();
11056 test_redundant_mode_set();
11057 test_coop_level_mode_set();
11058 test_coop_level_mode_set_multi();
11060 test_coop_level_surf_create();
11061 test_coop_level_multi_window();
11062 test_clear_rect_count();
11063 test_coop_level_versions();
11064 test_lighting_interface_versions();
11065 test_coop_level_activateapp();
11066 test_unsupported_formats();
11068 test_primary_caps();
11069 test_surface_lock();
11070 test_surface_discard();
11072 test_set_surface_desc();
11073 test_user_memory_getdc();
11074 test_sysmem_overlay();
11075 test_primary_palette();
11076 test_surface_attachment();
11077 test_pixel_format();
11078 test_create_surface_pitch();
11080 test_palette_complex();
11084 test_specular_lighting();
11085 test_palette_gdi();
11086 test_palette_alpha();
11087 test_lost_device();
11088 test_surface_desc_lock();
11089 test_texturemapblend();
11090 test_viewport_clear_rect();
11092 test_colorkey_precision();
11093 test_range_colorkey();
11095 test_lockrect_invalid();
11096 test_yv12_overlay();
11097 test_offscreen_overlay();
11098 test_overlay_rect();
11101 test_draw_primitive();
11102 test_edge_antialiasing_blending();
11103 test_transform_vertices();