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"
30 static BOOL is_ddraw64
= sizeof(DWORD
) != sizeof(DWORD
*);
31 static DEVMODEW registry_mode
;
33 static HRESULT (WINAPI
*pDwmIsCompositionEnabled
)(BOOL
*);
45 struct create_window_thread_param
48 HANDLE window_created
;
49 HANDLE destroy_window
;
53 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
55 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
57 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
59 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
61 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
65 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
75 if (abs(x
- y
) > ulps
)
81 static BOOL
compare_vec4(const struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
83 return compare_float(vec
->x
, x
, ulps
)
84 && compare_float(vec
->y
, y
, ulps
)
85 && compare_float(vec
->z
, z
, ulps
)
86 && compare_float(vec
->w
, w
, ulps
);
89 static BOOL
ddraw_get_identifier(IDirectDraw2
*ddraw
, DDDEVICEIDENTIFIER
*identifier
)
94 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirectDraw4
, (void **)&ddraw4
);
95 ok(SUCCEEDED(hr
), "Failed to get IDirectDraw4 interface, hr %#x.\n", hr
);
96 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw4
, identifier
, 0);
97 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#x.\n", hr
);
98 IDirectDraw4_Release(ddraw4
);
100 return SUCCEEDED(hr
);
103 static BOOL
ddraw_is_warp(IDirectDraw2
*ddraw
)
105 DDDEVICEIDENTIFIER identifier
;
107 return strcmp(winetest_platform
, "wine")
108 && ddraw_get_identifier(ddraw
, &identifier
)
109 && strstr(identifier
.szDriver
, "warp");
112 static BOOL
ddraw_is_vendor(IDirectDraw2
*ddraw
, DWORD vendor
)
114 DDDEVICEIDENTIFIER identifier
;
116 return strcmp(winetest_platform
, "wine")
117 && ddraw_get_identifier(ddraw
, &identifier
)
118 && identifier
.dwVendorId
== vendor
;
121 static BOOL
ddraw_is_intel(IDirectDraw2
*ddraw
)
123 return ddraw_is_vendor(ddraw
, 0x8086);
126 static BOOL
ddraw_is_nvidia(IDirectDraw2
*ddraw
)
128 return ddraw_is_vendor(ddraw
, 0x10de);
131 static BOOL
ddraw_is_vmware(IDirectDraw2
*ddraw
)
133 return ddraw_is_vendor(ddraw
, 0x15ad);
136 static IDirectDrawSurface
*create_overlay(IDirectDraw2
*ddraw
,
137 unsigned int width
, unsigned int height
, DWORD format
)
139 IDirectDrawSurface
*surface
;
142 memset(&desc
, 0, sizeof(desc
));
143 desc
.dwSize
= sizeof(desc
);
144 desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
145 desc
.dwWidth
= width
;
146 desc
.dwHeight
= height
;
147 desc
.ddsCaps
.dwCaps
= DDSCAPS_OVERLAY
;
148 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
149 desc
.ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
150 desc
.ddpfPixelFormat
.dwFourCC
= format
;
152 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &desc
, &surface
, NULL
)))
157 static HWND
create_window(void)
159 RECT r
= {0, 0, 640, 480};
161 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
163 return CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
164 CW_USEDEFAULT
, CW_USEDEFAULT
, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
167 static DWORD WINAPI
create_window_thread_proc(void *param
)
169 struct create_window_thread_param
*p
= param
;
173 p
->window
= create_window();
174 ret
= SetEvent(p
->window_created
);
175 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
181 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
182 DispatchMessageA(&msg
);
183 res
= WaitForSingleObject(p
->destroy_window
, 100);
184 if (res
== WAIT_OBJECT_0
)
186 if (res
!= WAIT_TIMEOUT
)
188 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
193 DestroyWindow(p
->window
);
198 static void create_window_thread(struct create_window_thread_param
*p
)
202 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
203 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
204 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
205 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
206 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
207 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
208 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
209 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
212 static void destroy_window_thread(struct create_window_thread_param
*p
)
214 SetEvent(p
->destroy_window
);
215 WaitForSingleObject(p
->thread
, INFINITE
);
216 CloseHandle(p
->destroy_window
);
217 CloseHandle(p
->window_created
);
218 CloseHandle(p
->thread
);
221 static IDirectDrawSurface
*get_depth_stencil(IDirect3DDevice2
*device
)
223 IDirectDrawSurface
*rt
, *ret
;
224 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
227 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
228 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
229 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ret
);
230 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
231 IDirectDrawSurface_Release(rt
);
235 static HRESULT
set_display_mode(IDirectDraw2
*ddraw
, DWORD width
, DWORD height
)
237 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
239 return IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0);
242 static D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
244 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
245 DDSURFACEDESC surface_desc
;
249 memset(&surface_desc
, 0, sizeof(surface_desc
));
250 surface_desc
.dwSize
= sizeof(surface_desc
);
252 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
253 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
257 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
259 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
260 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
265 static void check_rect(IDirectDrawSurface
*surface
, RECT r
, const char *message
)
267 LONG x_coords
[2][2] =
269 {r
.left
- 1, r
.left
+ 1},
270 {r
.right
+ 1, r
.right
- 1},
272 LONG y_coords
[2][2] =
274 {r
.top
- 1, r
.top
+ 1},
275 {r
.bottom
+ 1, r
.bottom
- 1}
277 unsigned int i
, j
, x_side
, y_side
;
281 for (i
= 0; i
< 2; ++i
)
283 for (j
= 0; j
< 2; ++j
)
285 for (x_side
= 0; x_side
< 2; ++x_side
)
287 for (y_side
= 0; y_side
< 2; ++y_side
)
289 DWORD expected
= (x_side
== 1 && y_side
== 1) ? 0x00ffffff : 0x00000000;
291 x
= x_coords
[i
][x_side
];
292 y
= y_coords
[j
][y_side
];
293 if (x
< 0 || x
>= 640 || y
< 0 || y
>= 480)
295 color
= get_surface_color(surface
, x
, y
);
296 ok(color
== expected
, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
297 message
, x
, y
, color
, expected
);
304 static DWORD
get_device_z_depth(IDirect3DDevice2
*device
)
306 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
307 IDirectDrawSurface
*ds
, *rt
;
311 if (FAILED(IDirect3DDevice2_GetRenderTarget(device
, &rt
)))
314 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ds
);
315 IDirectDrawSurface_Release(rt
);
319 desc
.dwSize
= sizeof(desc
);
320 hr
= IDirectDrawSurface_GetSurfaceDesc(ds
, &desc
);
321 IDirectDrawSurface_Release(ds
);
325 return U2(desc
).dwZBufferBitDepth
;
328 static IDirectDraw2
*create_ddraw(void)
330 IDirectDraw2
*ddraw2
;
334 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
337 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw2
);
338 IDirectDraw_Release(ddraw1
);
345 static IDirect3DDevice2
*create_device(IDirectDraw2
*ddraw
, HWND window
, DWORD coop_level
)
347 /* Prefer 16 bit depth buffers because Nvidia gives us an unpadded D24 buffer if we ask
348 * for 24 bit and handles such buffers incorrectly in DDBLT_DEPTHFILL. AMD only supports
349 * 16 bit buffers in ddraw1/2. Stencil was added in ddraw4, so we cannot create a D24S8
351 static const DWORD z_depths
[] = {16, 32, 24};
352 IDirectDrawSurface
*surface
, *ds
;
353 IDirect3DDevice2
*device
= NULL
;
354 DDSURFACEDESC surface_desc
;
359 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, coop_level
);
360 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
362 memset(&surface_desc
, 0, sizeof(surface_desc
));
363 surface_desc
.dwSize
= sizeof(surface_desc
);
364 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
365 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
366 surface_desc
.dwWidth
= 640;
367 surface_desc
.dwHeight
= 480;
369 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
370 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
372 if (coop_level
& DDSCL_NORMAL
)
374 IDirectDrawClipper
*clipper
;
376 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
377 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
378 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
379 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
380 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
381 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
382 IDirectDrawClipper_Release(clipper
);
385 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
388 IDirectDrawSurface_Release(surface
);
392 /* We used to use EnumDevices() for this, but it seems
393 * D3DDEVICEDESC.dwDeviceZBufferBitDepth only has a very casual
394 * relationship with reality. */
395 for (i
= 0; i
< ARRAY_SIZE(z_depths
); ++i
)
397 memset(&surface_desc
, 0, sizeof(surface_desc
));
398 surface_desc
.dwSize
= sizeof(surface_desc
);
399 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
400 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
401 U2(surface_desc
).dwZBufferBitDepth
= z_depths
[i
];
402 surface_desc
.dwWidth
= 640;
403 surface_desc
.dwHeight
= 480;
404 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
)))
407 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
408 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
409 IDirectDrawSurface_Release(ds
);
413 if (SUCCEEDED(IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
)))
416 IDirectDrawSurface_DeleteAttachedSurface(surface
, 0, ds
);
419 IDirect3D2_Release(d3d
);
420 IDirectDrawSurface_Release(surface
);
424 static IDirect3DViewport2
*create_viewport(IDirect3DDevice2
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
426 IDirect3DViewport2
*viewport
;
431 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
432 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
433 hr
= IDirect3D2_CreateViewport(d3d
, &viewport
, NULL
);
434 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
435 hr
= IDirect3DDevice2_AddViewport(device
, viewport
);
436 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
437 memset(&vp
, 0, sizeof(vp
));
438 vp
.dwSize
= sizeof(vp
);
445 vp
.dvClipWidth
= 2.0f
;
446 vp
.dvClipHeight
= 2.0f
;
449 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp
);
450 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
451 IDirect3D2_Release(d3d
);
456 static void viewport_set_background(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
,
457 IDirect3DMaterial2
*material
)
459 D3DMATERIALHANDLE material_handle
;
462 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &material_handle
);
463 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
464 hr
= IDirect3DViewport2_SetBackground(viewport
, material_handle
);
465 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
468 static void destroy_viewport(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
)
472 hr
= IDirect3DDevice2_DeleteViewport(device
, viewport
);
473 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
474 IDirect3DViewport2_Release(viewport
);
477 static IDirect3DMaterial2
*create_material(IDirect3DDevice2
*device
, D3DMATERIAL
*mat
)
479 IDirect3DMaterial2
*material
;
483 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
484 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
485 hr
= IDirect3D2_CreateMaterial(d3d
, &material
, NULL
);
486 ok(SUCCEEDED(hr
), "Failed to create material, hr %#x.\n", hr
);
487 hr
= IDirect3DMaterial2_SetMaterial(material
, mat
);
488 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
489 IDirect3D2_Release(d3d
);
494 static IDirect3DMaterial2
*create_diffuse_material(IDirect3DDevice2
*device
, float r
, float g
, float b
, float a
)
498 memset(&mat
, 0, sizeof(mat
));
499 mat
.dwSize
= sizeof(mat
);
500 U1(U(mat
).diffuse
).r
= r
;
501 U2(U(mat
).diffuse
).g
= g
;
502 U3(U(mat
).diffuse
).b
= b
;
503 U4(U(mat
).diffuse
).a
= a
;
505 return create_material(device
, &mat
);
508 static IDirect3DMaterial2
*create_diffuse_and_ambient_material(IDirect3DDevice2
*device
,
509 float r
, float g
, float b
, float a
)
513 memset(&mat
, 0, sizeof(mat
));
514 mat
.dwSize
= sizeof(mat
);
515 U1(U(mat
).diffuse
).r
= r
;
516 U2(U(mat
).diffuse
).g
= g
;
517 U3(U(mat
).diffuse
).b
= b
;
518 U4(U(mat
).diffuse
).a
= a
;
520 U1(U(mat
).ambient
).r
= r
;
521 U2(U(mat
).ambient
).g
= g
;
522 U3(U(mat
).ambient
).b
= b
;
523 U4(U(mat
).ambient
).a
= a
;
525 return create_material(device
, &mat
);
528 static IDirect3DMaterial2
*create_specular_material(IDirect3DDevice2
*device
,
529 float r
, float g
, float b
, float a
, float power
)
533 memset(&mat
, 0, sizeof(mat
));
534 mat
.dwSize
= sizeof(mat
);
535 U1(U2(mat
).specular
).r
= r
;
536 U2(U2(mat
).specular
).g
= g
;
537 U3(U2(mat
).specular
).b
= b
;
538 U4(U2(mat
).specular
).a
= a
;
539 U4(mat
).power
= power
;
541 return create_material(device
, &mat
);
544 static IDirect3DMaterial2
*create_emissive_material(IDirect3DDevice2
*device
, float r
, float g
, float b
, float a
)
548 memset(&mat
, 0, sizeof(mat
));
549 mat
.dwSize
= sizeof(mat
);
550 U1(U3(mat
).emissive
).r
= r
;
551 U2(U3(mat
).emissive
).g
= g
;
552 U3(U3(mat
).emissive
).b
= b
;
553 U4(U3(mat
).emissive
).a
= a
;
555 return create_material(device
, &mat
);
558 static void destroy_material(IDirect3DMaterial2
*material
)
560 IDirect3DMaterial2_Release(material
);
567 WPARAM expect_wparam
;
570 static const struct message
*expect_messages
;
572 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
574 if (expect_messages
&& message
== expect_messages
->message
)
576 if (expect_messages
->check_wparam
)
577 ok (wparam
== expect_messages
->expect_wparam
,
578 "Got unexpected wparam %lx for message %x, expected %lx.\n",
579 wparam
, message
, expect_messages
->expect_wparam
);
584 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
587 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
588 * interface. This prevents subsequent SetCooperativeLevel() calls on a
589 * different window from failing with DDERR_HWNDALREADYSET. */
590 static void fix_wndproc(HWND window
, LONG_PTR proc
)
595 if (!(ddraw
= create_ddraw()))
598 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
599 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
600 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
601 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
602 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
604 IDirectDraw2_Release(ddraw
);
607 static HRESULT CALLBACK
restore_callback(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
609 HRESULT hr
= IDirectDrawSurface_Restore(surface
);
610 ok(SUCCEEDED(hr
) || hr
== DDERR_IMPLICITLYCREATED
, "Failed to restore surface, hr %#x.\n", hr
);
611 IDirectDrawSurface_Release(surface
);
616 static HRESULT
restore_surfaces(IDirectDraw2
*ddraw
)
618 return IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
,
619 NULL
, NULL
, restore_callback
);
622 static void test_coop_level_create_device_window(void)
624 HWND focus_window
, device_window
;
628 focus_window
= create_window();
629 ddraw
= create_ddraw();
630 ok(!!ddraw
, "Failed to create a ddraw object.\n");
632 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
633 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
634 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
635 ok(!device_window
, "Unexpected device window found.\n");
636 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
637 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
638 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
639 ok(!device_window
, "Unexpected device window found.\n");
640 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
641 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
642 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
643 ok(!device_window
, "Unexpected device window found.\n");
644 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
645 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
646 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
647 ok(!device_window
, "Unexpected device window found.\n");
648 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
649 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
650 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
651 ok(!device_window
, "Unexpected device window found.\n");
653 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
654 if (broken(hr
== DDERR_INVALIDPARAMS
))
656 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
657 IDirectDraw2_Release(ddraw
);
658 DestroyWindow(focus_window
);
662 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
663 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
664 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
665 ok(!device_window
, "Unexpected device window found.\n");
666 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
667 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
668 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
669 ok(!device_window
, "Unexpected device window found.\n");
671 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
672 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
673 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
674 ok(!device_window
, "Unexpected device window found.\n");
675 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
676 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
677 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
678 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
679 ok(!!device_window
, "Device window not found.\n");
681 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
682 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
683 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
684 ok(!device_window
, "Unexpected device window found.\n");
685 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
686 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
687 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
688 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
689 ok(!!device_window
, "Device window not found.\n");
691 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
692 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
693 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
694 ok(!device_window
, "Unexpected device window found.\n");
695 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
696 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
697 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
698 ok(!device_window
, "Unexpected device window found.\n");
699 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
700 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
701 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
702 ok(!device_window
, "Unexpected device window found.\n");
703 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
704 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
705 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
706 ok(!!device_window
, "Device window not found.\n");
708 IDirectDraw2_Release(ddraw
);
709 DestroyWindow(focus_window
);
712 static void test_clipper_blt(void)
714 IDirectDrawSurface
*src_surface
, *dst_surface
;
715 RECT client_rect
, src_rect
;
716 IDirectDrawClipper
*clipper
;
717 DDSURFACEDESC surface_desc
;
718 unsigned int i
, j
, x
, y
;
730 static const DWORD src_data
[] =
732 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
733 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
734 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
736 static const D3DCOLOR expected1
[] =
738 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
739 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
740 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
741 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
743 /* Nvidia on Windows seems to have an off-by-one error
744 * when processing source rectangles. Our left = 1 and
745 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
746 * read as well, but only for the edge pixels on the
747 * output image. The bug happens on the y axis as well,
748 * but we only read one row there, and all source rows
749 * contain the same data. This bug is not dependent on
750 * the presence of a clipper. */
751 static const D3DCOLOR expected1_broken
[] =
753 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
754 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
755 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
756 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
758 static const D3DCOLOR expected2
[] =
760 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
761 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
762 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
763 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
766 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
767 10, 10, 640, 480, 0, 0, 0, 0);
768 ShowWindow(window
, SW_SHOW
);
769 ddraw
= create_ddraw();
770 ok(!!ddraw
, "Failed to create a ddraw object.\n");
772 ret
= GetClientRect(window
, &client_rect
);
773 ok(ret
, "Failed to get client rect.\n");
774 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
775 ok(ret
, "Failed to map client rect.\n");
777 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
778 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
780 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
781 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
782 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
783 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
784 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
785 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
786 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
787 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
788 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
789 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
790 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
791 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
792 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
793 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
794 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
795 "Got unexpected bounding rect %s, expected %s.\n",
796 wine_dbgstr_rect(&rgn_data
->rdh
.rcBound
), wine_dbgstr_rect(&client_rect
));
797 HeapFree(GetProcessHeap(), 0, rgn_data
);
799 r1
= CreateRectRgn(0, 0, 320, 240);
800 ok(!!r1
, "Failed to create region.\n");
801 r2
= CreateRectRgn(320, 240, 640, 480);
802 ok(!!r2
, "Failed to create region.\n");
803 CombineRgn(r1
, r1
, r2
, RGN_OR
);
804 ret
= GetRegionData(r1
, 0, NULL
);
805 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
806 ret
= GetRegionData(r1
, ret
, rgn_data
);
807 ok(!!ret
, "Failed to get region data.\n");
812 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
813 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
814 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
815 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
816 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
817 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
819 HeapFree(GetProcessHeap(), 0, rgn_data
);
821 memset(&surface_desc
, 0, sizeof(surface_desc
));
822 surface_desc
.dwSize
= sizeof(surface_desc
);
823 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
824 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
825 surface_desc
.dwWidth
= 640;
826 surface_desc
.dwHeight
= 480;
827 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
828 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
829 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
830 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
831 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
832 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
834 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
835 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
836 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
837 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
839 memset(&fx
, 0, sizeof(fx
));
840 fx
.dwSize
= sizeof(fx
);
841 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
842 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
843 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
844 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
846 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
847 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
848 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
849 ptr
= surface_desc
.lpSurface
;
850 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
851 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
852 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
853 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
854 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
856 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
857 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
859 SetRect(&src_rect
, 1, 1, 5, 2);
860 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
861 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
862 for (i
= 0; i
< 4; ++i
)
864 for (j
= 0; j
< 4; ++j
)
866 x
= 80 * ((2 * j
) + 1);
867 y
= 60 * ((2 * i
) + 1);
868 color
= get_surface_color(dst_surface
, x
, y
);
869 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
870 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
871 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
875 U5(fx
).dwFillColor
= 0xff0000ff;
876 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
877 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
878 for (i
= 0; i
< 4; ++i
)
880 for (j
= 0; j
< 4; ++j
)
882 x
= 80 * ((2 * j
) + 1);
883 y
= 60 * ((2 * i
) + 1);
884 color
= get_surface_color(dst_surface
, x
, y
);
885 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
886 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
890 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
891 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#x.\n", hr
);
893 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
894 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
895 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
896 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
897 DestroyWindow(window
);
898 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
899 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
900 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
901 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
902 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
903 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
904 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
905 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
906 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
907 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
908 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
909 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
911 IDirectDrawSurface_Release(dst_surface
);
912 IDirectDrawSurface_Release(src_surface
);
913 refcount
= IDirectDrawClipper_Release(clipper
);
914 ok(!refcount
, "Clipper has %u references left.\n", refcount
);
915 IDirectDraw2_Release(ddraw
);
918 static void test_coop_level_d3d_state(void)
920 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
921 IDirectDrawSurface
*rt
, *surface
;
922 IDirect3DMaterial2
*background
;
923 IDirect3DViewport2
*viewport
;
924 IDirect3DDevice2
*device
;
925 D3DMATERIAL material
;
932 window
= create_window();
933 ddraw
= create_ddraw();
934 ok(!!ddraw
, "Failed to create a ddraw object.\n");
935 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
937 skip("Failed to create a 3D device, skipping test.\n");
938 IDirectDraw2_Release(ddraw
);
939 DestroyWindow(window
);
943 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
944 viewport
= create_viewport(device
, 0, 0, 640, 480);
945 viewport_set_background(device
, viewport
, background
);
947 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
948 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
949 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
950 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
951 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
952 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
953 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
954 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
955 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
956 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
957 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
958 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
959 color
= get_surface_color(rt
, 320, 240);
960 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
962 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
963 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
964 hr
= IDirectDrawSurface_IsLost(rt
);
965 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
966 hr
= restore_surfaces(ddraw
);
967 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
969 memset(&material
, 0, sizeof(material
));
970 material
.dwSize
= sizeof(material
);
971 U1(U(material
).diffuse
).r
= 0.0f
;
972 U2(U(material
).diffuse
).g
= 1.0f
;
973 U3(U(material
).diffuse
).b
= 0.0f
;
974 U4(U(material
).diffuse
).a
= 1.0f
;
975 hr
= IDirect3DMaterial2_SetMaterial(background
, &material
);
976 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
978 hr
= IDirect3DDevice2_GetRenderTarget(device
, &surface
);
979 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
980 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
981 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
982 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
983 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
984 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
985 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
986 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
987 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
988 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
989 color
= get_surface_color(rt
, 320, 240);
990 ok(compare_color(color
, 0x0000ff00, 1) || broken(compare_color(color
, 0x00000000, 1)),
991 "Got unexpected color 0x%08x.\n", color
);
993 destroy_viewport(device
, viewport
);
994 destroy_material(background
);
995 IDirectDrawSurface_Release(surface
);
996 IDirectDrawSurface_Release(rt
);
997 IDirect3DDevice2_Release(device
);
998 IDirectDraw2_Release(ddraw
);
999 DestroyWindow(window
);
1002 static void test_surface_interface_mismatch(void)
1004 IDirectDraw2
*ddraw
= NULL
;
1005 IDirect3D2
*d3d
= NULL
;
1006 IDirectDrawSurface
*surface
= NULL
, *ds
;
1007 IDirectDrawSurface3
*surface3
= NULL
;
1008 IDirect3DDevice2
*device
= NULL
;
1009 IDirect3DViewport2
*viewport
= NULL
;
1010 IDirect3DMaterial2
*background
= NULL
;
1011 DDSURFACEDESC surface_desc
;
1017 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1019 window
= create_window();
1020 ddraw
= create_ddraw();
1021 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1022 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1024 skip("Failed to create a 3D device, skipping test.\n");
1025 IDirectDraw2_Release(ddraw
);
1026 DestroyWindow(window
);
1029 z_depth
= get_device_z_depth(device
);
1030 ok(!!z_depth
, "Failed to get device z depth.\n");
1031 IDirect3DDevice2_Release(device
);
1034 memset(&surface_desc
, 0, sizeof(surface_desc
));
1035 surface_desc
.dwSize
= sizeof(surface_desc
);
1036 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1037 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
1038 surface_desc
.dwWidth
= 640;
1039 surface_desc
.dwHeight
= 480;
1041 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1042 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1044 hr
= IDirectDrawSurface2_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
1047 skip("Failed to get the IDirectDrawSurface3 interface, skipping test.\n");
1051 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
1053 skip("D3D interface is not available, skipping test.\n");
1057 memset(&surface_desc
, 0, sizeof(surface_desc
));
1058 surface_desc
.dwSize
= sizeof(surface_desc
);
1059 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
1060 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1061 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
1062 surface_desc
.dwWidth
= 640;
1063 surface_desc
.dwHeight
= 480;
1064 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
1065 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
1069 /* Using a different surface interface version still works */
1070 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
1071 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
1072 refcount
= IDirectDrawSurface_Release(ds
);
1073 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
1078 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface
*)surface3
, &device
);
1079 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
1083 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1084 viewport
= create_viewport(device
, 0, 0, 640, 480);
1085 viewport_set_background(device
, viewport
, background
);
1087 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1088 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1089 color
= get_surface_color(surface
, 320, 240);
1090 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1094 destroy_viewport(device
, viewport
);
1096 destroy_material(background
);
1097 if (surface3
) IDirectDrawSurface3_Release(surface3
);
1098 if (surface
) IDirectDrawSurface_Release(surface
);
1099 if (device
) IDirect3DDevice2_Release(device
);
1100 if (d3d
) IDirect3D2_Release(d3d
);
1101 if (ddraw
) IDirectDraw2_Release(ddraw
);
1102 DestroyWindow(window
);
1105 static void test_coop_level_threaded(void)
1107 struct create_window_thread_param p
;
1108 IDirectDraw2
*ddraw
;
1111 ddraw
= create_ddraw();
1112 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1113 create_window_thread(&p
);
1115 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1116 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1118 IDirectDraw2_Release(ddraw
);
1119 destroy_window_thread(&p
);
1122 static void test_depth_blit(void)
1124 static D3DLVERTEX quad1
[] =
1126 {{-1.0}, { 1.0}, {0.50f
}, 0, {0xff00ff00}},
1127 {{ 1.0}, { 1.0}, {0.50f
}, 0, {0xff00ff00}},
1128 {{-1.0}, {-1.0}, {0.50f
}, 0, {0xff00ff00}},
1129 {{ 1.0}, {-1.0}, {0.50f
}, 0, {0xff00ff00}},
1131 static const D3DCOLOR expected_colors
[4][4] =
1133 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1134 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1135 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1136 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1138 DDSURFACEDESC ddsd_new
, ddsd_existing
;
1140 IDirect3DDevice2
*device
;
1141 IDirectDrawSurface
*ds1
, *ds2
, *ds3
, *rt
;
1142 IDirect3DViewport2
*viewport
;
1143 RECT src_rect
, dst_rect
;
1147 IDirectDraw2
*ddraw
;
1151 IDirect3DMaterial2
*background
;
1153 window
= create_window();
1154 ddraw
= create_ddraw();
1155 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1156 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1158 skip("Failed to create a 3D device, skipping test.\n");
1159 IDirectDraw2_Release(ddraw
);
1160 DestroyWindow(window
);
1164 ds1
= get_depth_stencil(device
);
1166 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1167 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1168 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1169 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1170 hr
= IDirectDrawSurface_GetSurfaceDesc(ds1
, &ddsd_existing
);
1171 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
1172 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1173 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1174 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1175 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1176 ddsd_new
.ddpfPixelFormat
= ddsd_existing
.ddpfPixelFormat
;
1177 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1178 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1179 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1180 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1182 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1183 viewport
= create_viewport(device
, 0, 0, ddsd_existing
.dwWidth
, ddsd_existing
.dwHeight
);
1184 viewport_set_background(device
, viewport
, background
);
1185 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1186 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
1188 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1189 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
1190 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1191 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
1193 U1(d3drect
).x1
= U2(d3drect
).y1
= 0;
1194 U3(d3drect
).x2
= ddsd_existing
.dwWidth
; U4(d3drect
).y2
= ddsd_existing
.dwHeight
;
1195 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
);
1196 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
1199 SetRect(&src_rect
, 0, 0, 320, 240);
1200 SetRect(&dst_rect
, 0, 0, 320, 240);
1201 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1202 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1203 /* Different locations. */
1204 SetRect(&src_rect
, 0, 0, 320, 240);
1205 SetRect(&dst_rect
, 320, 240, 640, 480);
1206 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1207 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1209 SetRect(&src_rect
, 0, 0, 320, 240);
1210 SetRect(&dst_rect
, 0, 0, 640, 480);
1211 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1212 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1214 SetRect(&src_rect
, 0, 480, 640, 0);
1215 SetRect(&dst_rect
, 0, 0, 640, 480);
1216 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1217 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1218 SetRect(&src_rect
, 0, 0, 640, 480);
1219 SetRect(&dst_rect
, 0, 480, 640, 0);
1220 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1221 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1222 /* Full, explicit. */
1223 SetRect(&src_rect
, 0, 0, 640, 480);
1224 SetRect(&dst_rect
, 0, 0, 640, 480);
1225 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1226 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1227 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1229 /* Depth blit inside a BeginScene / EndScene pair */
1230 hr
= IDirect3DDevice2_BeginScene(device
);
1231 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1232 /* From the current depth stencil */
1233 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1234 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1235 /* To the current depth stencil */
1236 hr
= IDirectDrawSurface_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1237 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1238 /* Between unbound surfaces */
1239 hr
= IDirectDrawSurface_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1240 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1241 hr
= IDirect3DDevice2_EndScene(device
);
1242 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1244 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1245 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1246 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1247 * a reliable result(z = 0.0) */
1248 memset(&fx
, 0, sizeof(fx
));
1249 fx
.dwSize
= sizeof(fx
);
1250 U5(fx
).dwFillDepth
= 0;
1251 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1252 ok(SUCCEEDED(hr
), "Failed to clear the source z buffer, hr %#x.\n", hr
);
1254 /* This clears the Z buffer with 1.0 */
1255 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
);
1256 ok(SUCCEEDED(hr
), "Failed to clear the color and z buffers, hr %#x.\n", hr
);
1258 SetRect(&dst_rect
, 0, 0, 320, 240);
1259 hr
= IDirectDrawSurface_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1260 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1261 IDirectDrawSurface_Release(ds3
);
1262 IDirectDrawSurface_Release(ds2
);
1263 IDirectDrawSurface_Release(ds1
);
1265 hr
= IDirect3DDevice2_BeginScene(device
);
1266 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1267 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad1
, 4, 0);
1268 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1269 hr
= IDirect3DDevice2_EndScene(device
);
1270 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1272 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1273 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1274 for (i
= 0; i
< 4; ++i
)
1276 for (j
= 0; j
< 4; ++j
)
1278 unsigned int x
= 80 * ((2 * j
) + 1);
1279 unsigned int y
= 60 * ((2 * i
) + 1);
1280 color
= get_surface_color(rt
, x
, y
);
1281 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1282 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1285 IDirectDrawSurface_Release(rt
);
1287 destroy_viewport(device
, viewport
);
1288 destroy_material(background
);
1289 IDirect3DDevice2_Release(device
);
1290 IDirectDraw2_Release(ddraw
);
1291 DestroyWindow(window
);
1294 static void test_texture_load_ckey(void)
1296 IDirectDraw2
*ddraw
= NULL
;
1297 IDirectDrawSurface
*src
= NULL
;
1298 IDirectDrawSurface
*dst
= NULL
;
1299 IDirect3DTexture
*src_tex
= NULL
;
1300 IDirect3DTexture
*dst_tex
= NULL
;
1305 ddraw
= create_ddraw();
1306 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1307 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1308 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1310 memset(&ddsd
, 0, sizeof(ddsd
));
1311 ddsd
.dwSize
= sizeof(ddsd
);
1312 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1313 ddsd
.dwHeight
= 128;
1315 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1316 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1317 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1318 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1319 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1320 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1322 hr
= IDirectDrawSurface_QueryInterface(src
, &IID_IDirect3DTexture
, (void **)&src_tex
);
1323 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get Direct3DTexture interface, hr %#x.\n", hr
);
1326 /* 64 bit ddraw does not support d3d */
1327 skip("Could not get Direct3DTexture interface, skipping texture::Load color keying tests.\n");
1330 hr
= IDirectDrawSurface_QueryInterface(dst
, &IID_IDirect3DTexture
, (void **)&dst_tex
);
1331 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture interface, hr %#x.\n", hr
);
1333 /* No surface has a color key */
1334 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1335 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDCAPS
), "Got unexpected hr %#x.\n", hr
);
1338 /* Testbot Windows NT VMs */
1339 skip("IDirect3DTexture::Load does not work, skipping color keying tests.\n");
1343 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1344 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1345 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1346 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1347 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1349 /* Source surface has a color key */
1350 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1351 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1352 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1353 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1354 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1355 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1356 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1357 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1358 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1360 /* Both surfaces have a color key: Dest ckey is overwritten */
1361 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1362 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1363 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1364 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1365 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1366 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1367 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1368 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1369 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1371 /* Only the destination has a color key: It is not deleted */
1372 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1373 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1374 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1375 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1376 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1377 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1378 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1379 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1380 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1381 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1384 if (dst_tex
) IDirect3DTexture_Release(dst_tex
);
1385 if (src_tex
) IDirect3DTexture_Release(src_tex
);
1386 if (dst
) IDirectDrawSurface_Release(dst
);
1387 if (src
) IDirectDrawSurface_Release(src
);
1388 if (ddraw
) IDirectDraw2_Release(ddraw
);
1391 static ULONG
get_refcount(IUnknown
*test_iface
)
1393 IUnknown_AddRef(test_iface
);
1394 return IUnknown_Release(test_iface
);
1397 static void test_viewport_object(void)
1399 IDirectDraw2
*ddraw
;
1402 ULONG ref
, old_d3d_ref
;
1405 IDirect3DViewport
*viewport
;
1406 IDirect3DViewport2
*viewport2
, *another_vp
, *test_vp
;
1407 IDirect3DViewport3
*viewport3
;
1408 IDirectDrawGammaControl
*gamma
;
1410 IDirect3DDevice2
*device
;
1419 window
= create_window();
1420 ddraw
= create_ddraw();
1421 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1422 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1424 skip("Failed to create a 3D device, skipping test.\n");
1425 IDirectDraw_Release(ddraw
);
1426 DestroyWindow(window
);
1430 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
1431 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get d3d interface, hr %#x.\n", hr
);
1434 skip("D3D interface is not available, skipping test.\n");
1435 IDirectDraw2_Release(ddraw
);
1438 old_d3d_ref
= get_refcount((IUnknown
*)d3d
);
1440 hr
= IDirect3D2_CreateViewport(d3d
, &viewport2
, NULL
);
1441 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1442 ref
= get_refcount((IUnknown
*)viewport2
);
1443 ok(ref
== 1, "Got unexpected refcount %u.\n", ref
);
1444 ref
= get_refcount((IUnknown
*)d3d
);
1445 ok(ref
== old_d3d_ref
, "Got unexpected refcount %u.\n", ref
);
1447 memset(&desc
, 0, sizeof(desc
));
1448 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1449 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1450 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) + 1;
1451 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1452 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1453 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) - 1;
1454 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1455 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1456 desc
.vp1
.dwSize
= sizeof(desc
.vp1
);
1457 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1458 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#x.\n", hr
);
1459 ok(desc
.vp1
.dwSize
== sizeof(desc
.vp1
), "Got unexpected dwSize %u.\n", desc
.vp1
.dwSize
);
1460 hr
= IDirect3DViewport2_GetViewport2(viewport2
, &desc
.vp2
);
1461 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#x.\n", hr
);
1462 ok(desc
.vp2
.dwSize
== sizeof(desc
.vp2
), "Got unexpected dwSize %u.\n", desc
.vp2
.dwSize
);
1463 desc
.vp2
.dwSize
= sizeof(desc
.vp2
) + 1;
1464 hr
= IDirect3DViewport2_GetViewport2(viewport2
, &desc
.vp2
);
1465 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1467 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1468 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1469 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
1470 ok(!gamma
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1471 /* NULL iid: Segfaults */
1473 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport
, (void **)&viewport
);
1474 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport, hr %#x.\n", hr
);
1475 ref
= get_refcount((IUnknown
*)viewport
);
1476 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1477 ref
= get_refcount((IUnknown
*)viewport2
);
1478 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1479 IDirect3DViewport_Release(viewport
);
1482 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport3
, (void **)&viewport3
);
1483 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to QI IDirect3DViewport3, hr %#x.\n", hr
);
1486 ref
= get_refcount((IUnknown
*)viewport2
);
1487 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1488 ref
= get_refcount((IUnknown
*)viewport3
);
1489 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1490 IDirect3DViewport3_Release(viewport3
);
1493 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IUnknown
, (void **)&unknown
);
1494 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#x.\n", hr
);
1495 ref
= get_refcount((IUnknown
*)viewport2
);
1496 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1497 ref
= get_refcount(unknown
);
1498 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1499 IUnknown_Release(unknown
);
1501 hr
= IDirect3DDevice2_DeleteViewport(device
, NULL
);
1502 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1503 hr
= IDirect3DDevice2_GetCurrentViewport(device
, NULL
);
1504 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1506 hr
= IDirect3D2_CreateViewport(d3d
, &another_vp
, NULL
);
1507 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1509 /* Setting a viewport not in the viewport list fails */
1510 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1511 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1513 /* AddViewport(NULL): Segfault */
1514 hr
= IDirect3DDevice2_AddViewport(device
, viewport2
);
1515 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1516 ref
= get_refcount((IUnknown
*) viewport2
);
1517 ok(ref
== 2, "viewport2 refcount is %u.\n", ref
);
1518 hr
= IDirect3DDevice2_AddViewport(device
, another_vp
);
1519 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1520 ref
= get_refcount((IUnknown
*) another_vp
);
1521 ok(ref
== 2, "another_vp refcount is %u.\n", ref
);
1523 test_vp
= (IDirect3DViewport2
*) 0xbaadc0de;
1524 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1525 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1526 ok(test_vp
== (IDirect3DViewport2
*) 0xbaadc0de, "Got unexpected pointer %p\n", test_vp
);
1528 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1529 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1530 ref
= get_refcount((IUnknown
*) viewport2
);
1531 ok(ref
== 3, "Got unexpected refcount %u.\n", ref
);
1532 ref
= get_refcount((IUnknown
*) device
);
1533 ok(ref
== 1, "Got unexpected refcount %u.\n", ref
);
1536 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1537 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1538 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1539 ref
= get_refcount((IUnknown
*) viewport2
);
1540 ok(ref
== 4, "Got unexpected refcount %u.\n", ref
);
1542 IDirect3DViewport2_Release(test_vp
);
1544 /* GetCurrentViewport with a viewport set and NULL input param: Segfault */
1546 /* Cannot set the viewport to NULL */
1547 hr
= IDirect3DDevice2_SetCurrentViewport(device
, NULL
);
1548 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to set viewport to NULL, hr %#x.\n", hr
);
1550 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1551 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1552 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1554 IDirect3DViewport2_Release(test_vp
);
1556 /* SetCurrentViewport properly releases the old viewport's reference */
1557 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1558 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1559 ref
= get_refcount((IUnknown
*) viewport2
);
1560 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1561 ref
= get_refcount((IUnknown
*) another_vp
);
1562 ok(ref
== 3, "Got unexpected refcount %u.\n", ref
);
1564 /* Deleting the viewport removes the reference added by AddViewport, but not
1565 * the one added by SetCurrentViewport. */
1566 hr
= IDirect3DDevice2_DeleteViewport(device
, another_vp
);
1567 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#x.\n", hr
);
1568 ref
= get_refcount((IUnknown
*) another_vp
);
1569 todo_wine
ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1571 /* GetCurrentViewport fails though */
1573 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1574 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1575 ok(!test_vp
, "Got unexpected viewport %p\n", test_vp
);
1577 /* Setting a different viewport does not free the leaked reference. How
1578 * do I get rid of it? Leak the viewport for now. */
1579 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1580 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1581 ref
= get_refcount((IUnknown
*) viewport2
);
1582 ok(ref
== 3, "Got unexpected refcount %u.\n", ref
);
1583 ref
= get_refcount((IUnknown
*) another_vp
);
1584 todo_wine
ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1586 memset(&vp
, 0, sizeof(vp
));
1587 memset(&vp
, 0, sizeof(vp2
));
1588 vp
.dwX
= vp2
.dwX
= 0;
1589 vp
.dwY
= vp2
.dwY
= 0;
1590 vp
.dwWidth
= vp2
.dwWidth
= 640;
1591 vp
.dwHeight
= vp2
.dwHeight
= 480;
1592 vp
.dvMinZ
= vp2
.dvMinZ
= 0.0f
;
1593 vp
.dvMaxZ
= vp2
.dvMaxZ
= 1.0f
;
1594 vp
.dvScaleX
= vp
.dwWidth
/ 2.0f
;
1595 vp
.dvScaleY
= vp
.dwHeight
/ 2.0f
;
1598 vp2
.dvClipX
= -1.0f
;
1600 vp2
.dvClipWidth
= 2.0f
;
1601 vp2
.dvClipHeight
= 2.0f
;
1602 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1603 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1604 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1605 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1607 vp
.dwSize
= sizeof(vp
);
1608 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1609 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
1610 vp2
.dwSize
= sizeof(vp2
);
1611 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1612 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
1614 /* Destroying the device removes the viewport, but does not free the reference
1615 * added by SetCurrentViewport. */
1616 IDirect3DDevice2_Release(device
);
1617 ref
= get_refcount((IUnknown
*) viewport2
);
1618 todo_wine
ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1620 vp
.dwSize
= sizeof(vp
);
1621 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1622 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#x.\n", hr
);
1623 vp2
.dwSize
= sizeof(vp2
);
1624 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1625 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#x.\n", hr
);
1627 IDirect3DViewport2_Release(another_vp
);
1628 IDirect3DViewport2_Release(viewport2
);
1629 IDirect3D2_Release(d3d
);
1630 DestroyWindow(window
);
1631 IDirectDraw2_Release(ddraw
);
1634 static void test_zenable(void)
1636 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1637 static D3DTLVERTEX tquad
[] =
1639 {{ 0.0f
}, {480.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1640 {{ 0.0f
}, { 0.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1641 {{640.0f
}, {480.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1642 {{640.0f
}, { 0.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1644 IDirect3DMaterial2
*background
;
1645 IDirect3DViewport2
*viewport
;
1646 IDirect3DDevice2
*device
;
1647 IDirectDrawSurface
*rt
;
1648 IDirectDraw2
*ddraw
;
1655 window
= create_window();
1656 ddraw
= create_ddraw();
1657 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1658 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1660 skip("Failed to create a 3D device, skipping test.\n");
1661 IDirectDraw2_Release(ddraw
);
1662 DestroyWindow(window
);
1666 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1667 viewport
= create_viewport(device
, 0, 0, 640, 480);
1668 viewport_set_background(device
, viewport
, background
);
1669 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1670 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1672 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1673 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
1675 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1676 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1677 hr
= IDirect3DDevice2_BeginScene(device
);
1678 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1679 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, tquad
, 4, 0);
1680 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1681 hr
= IDirect3DDevice2_EndScene(device
);
1682 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1684 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1685 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1686 for (i
= 0; i
< 4; ++i
)
1688 for (j
= 0; j
< 4; ++j
)
1690 x
= 80 * ((2 * j
) + 1);
1691 y
= 60 * ((2 * i
) + 1);
1692 color
= get_surface_color(rt
, x
, y
);
1693 ok(compare_color(color
, 0x0000ff00, 1),
1694 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1697 IDirectDrawSurface_Release(rt
);
1699 destroy_viewport(device
, viewport
);
1700 destroy_material(background
);
1701 IDirect3DDevice2_Release(device
);
1702 IDirectDraw2_Release(ddraw
);
1703 DestroyWindow(window
);
1706 static void test_ck_rgba(void)
1708 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1709 static D3DTLVERTEX tquad
[] =
1711 {{ 0.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1712 {{ 0.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1713 {{640.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1714 {{640.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1715 {{ 0.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1716 {{ 0.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1717 {{640.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1718 {{640.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1722 D3DCOLOR fill_color
;
1725 D3DCOLOR result1
, result1_broken
;
1726 D3DCOLOR result2
, result2_broken
;
1730 /* r200 on Windows doesn't check the alpha component when applying the color
1731 * key, so the key matches on every texel. */
1732 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1733 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1734 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1735 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1736 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00ff0000, 0x00807f00, 0x000000ff},
1737 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000, 0x0000ff00, 0x000000ff},
1738 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00, 0x00807f00, 0x00807f00},
1739 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1742 D3DTEXTUREHANDLE texture_handle
;
1743 IDirect3DMaterial2
*background
;
1744 IDirectDrawSurface
*surface
;
1745 IDirect3DViewport2
*viewport
;
1746 IDirect3DTexture2
*texture
;
1747 DDSURFACEDESC surface_desc
;
1748 IDirect3DDevice2
*device
;
1749 IDirectDrawSurface
*rt
;
1750 IDirectDraw2
*ddraw
;
1757 window
= create_window();
1758 ddraw
= create_ddraw();
1759 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1760 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1762 skip("Failed to create a 3D device, skipping test.\n");
1763 IDirectDraw2_Release(ddraw
);
1764 DestroyWindow(window
);
1768 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1769 viewport
= create_viewport(device
, 0, 0, 640, 480);
1770 viewport_set_background(device
, viewport
, background
);
1771 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1772 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1774 memset(&surface_desc
, 0, sizeof(surface_desc
));
1775 surface_desc
.dwSize
= sizeof(surface_desc
);
1776 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1777 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1778 surface_desc
.dwWidth
= 256;
1779 surface_desc
.dwHeight
= 256;
1780 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1781 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1782 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1783 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1784 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1785 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1786 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1787 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1788 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1789 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1790 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1791 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1792 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1793 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
1794 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1795 IDirect3DTexture2_Release(texture
);
1797 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1798 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1799 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1800 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1801 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1802 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1804 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1805 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1807 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
1809 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1810 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1811 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1812 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1814 memset(&fx
, 0, sizeof(fx
));
1815 fx
.dwSize
= sizeof(fx
);
1816 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1817 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1818 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1820 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
1821 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1822 hr
= IDirect3DDevice2_BeginScene(device
);
1823 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1824 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
1825 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1826 hr
= IDirect3DDevice2_EndScene(device
);
1827 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1829 color
= get_surface_color(rt
, 320, 240);
1830 ok(compare_color(color
, tests
[i
].result1
, 1) || compare_color(color
, tests
[i
].result1_broken
, 1),
1831 "Expected color 0x%08x for test %u, got 0x%08x.\n",
1832 tests
[i
].result1
, i
, color
);
1834 U5(fx
).dwFillColor
= 0xff0000ff;
1835 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1836 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1838 hr
= IDirect3DDevice2_BeginScene(device
);
1839 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1840 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[4], 4, 0);
1841 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1842 hr
= IDirect3DDevice2_EndScene(device
);
1843 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1845 /* This tests that fragments that are masked out by the color key are
1846 * discarded, instead of just fully transparent. */
1847 color
= get_surface_color(rt
, 320, 240);
1848 ok(compare_color(color
, tests
[i
].result2
, 1) || compare_color(color
, tests
[i
].result2_broken
, 1),
1849 "Expected color 0x%08x for test %u, got 0x%08x.\n",
1850 tests
[i
].result2
, i
, color
);
1853 IDirectDrawSurface_Release(rt
);
1854 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1855 ok(SUCCEEDED(hr
), "Failed to unset texture, hr %#x.\n", hr
);
1856 IDirectDrawSurface_Release(surface
);
1857 destroy_viewport(device
, viewport
);
1858 destroy_material(background
);
1859 IDirect3DDevice2_Release(device
);
1860 IDirectDraw2_Release(ddraw
);
1861 DestroyWindow(window
);
1864 static void test_ck_default(void)
1866 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1867 static D3DTLVERTEX tquad
[] =
1869 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1870 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1871 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1872 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1874 IDirectDrawSurface
*surface
, *rt
;
1875 D3DTEXTUREHANDLE texture_handle
;
1876 IDirect3DMaterial2
*background
;
1877 IDirect3DViewport2
*viewport
;
1878 DDSURFACEDESC surface_desc
;
1879 IDirect3DTexture2
*texture
;
1880 IDirect3DDevice2
*device
;
1881 IDirectDraw2
*ddraw
;
1888 window
= create_window();
1889 ddraw
= create_ddraw();
1890 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1891 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1893 skip("Failed to create a 3D device, skipping test.\n");
1894 IDirectDraw2_Release(ddraw
);
1895 DestroyWindow(window
);
1899 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1900 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1902 background
= create_diffuse_material(device
, 0.0, 1.0f
, 0.0f
, 1.0f
);
1903 viewport
= create_viewport(device
, 0, 0, 640, 480);
1904 viewport_set_background(device
, viewport
, background
);
1905 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1906 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1908 memset(&surface_desc
, 0, sizeof(surface_desc
));
1909 surface_desc
.dwSize
= sizeof(surface_desc
);
1910 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1911 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1912 surface_desc
.dwWidth
= 256;
1913 surface_desc
.dwHeight
= 256;
1914 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1915 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1916 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1917 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1918 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1919 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1920 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
1921 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
1922 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1923 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1924 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1925 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1926 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
1927 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1928 IDirect3DTexture_Release(texture
);
1930 memset(&fx
, 0, sizeof(fx
));
1931 fx
.dwSize
= sizeof(fx
);
1932 U5(fx
).dwFillColor
= 0x000000ff;
1933 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1934 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
1936 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1937 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1938 hr
= IDirect3DDevice2_BeginScene(device
);
1939 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1940 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1941 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
1942 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1943 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1944 ok(!value
, "Got unexpected color keying state %#x.\n", value
);
1945 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
1946 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1947 hr
= IDirect3DDevice2_EndScene(device
);
1948 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1949 color
= get_surface_color(rt
, 320, 240);
1950 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1952 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1953 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1954 hr
= IDirect3DDevice2_BeginScene(device
);
1955 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1956 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
1957 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1958 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
1959 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1960 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1961 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1962 ok(!!value
, "Got unexpected color keying state %#x.\n", value
);
1963 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1964 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
1965 hr
= IDirect3DDevice2_EndScene(device
);
1966 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1967 color
= get_surface_color(rt
, 320, 240);
1968 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1970 IDirectDrawSurface_Release(surface
);
1971 destroy_viewport(device
, viewport
);
1972 destroy_material(background
);
1973 IDirectDrawSurface_Release(rt
);
1974 IDirect3DDevice2_Release(device
);
1975 IDirectDraw2_Release(ddraw
);
1976 DestroyWindow(window
);
1979 static void test_ck_complex(void)
1981 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
1982 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
1983 DDSURFACEDESC surface_desc
;
1984 IDirect3DDevice2
*device
;
1985 DDCOLORKEY color_key
;
1986 IDirectDraw2
*ddraw
;
1992 window
= create_window();
1993 ddraw
= create_ddraw();
1994 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1995 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
1997 skip("Failed to create a 3D device, skipping test.\n");
1998 DestroyWindow(window
);
1999 IDirectDraw2_Release(ddraw
);
2002 IDirect3DDevice2_Release(device
);
2004 memset(&surface_desc
, 0, sizeof(surface_desc
));
2005 surface_desc
.dwSize
= sizeof(surface_desc
);
2006 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2007 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
2008 surface_desc
.dwWidth
= 128;
2009 surface_desc
.dwHeight
= 128;
2010 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2011 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2013 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2014 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2015 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2016 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2017 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2018 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2019 memset(&color_key
, 0, sizeof(color_key
));
2020 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2021 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2022 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2023 color_key
.dwColorSpaceLowValue
);
2024 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2025 color_key
.dwColorSpaceHighValue
);
2028 IDirectDrawSurface_AddRef(mipmap
);
2029 for (i
= 0; i
< 7; ++i
)
2031 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2032 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
2034 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2035 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2036 color_key
.dwColorSpaceLowValue
= 0x000000ff;
2037 color_key
.dwColorSpaceHighValue
= 0x000000ff;
2038 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2039 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x, i %u.\n", hr
, i
);
2040 memset(&color_key
, 0, sizeof(color_key
));
2041 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2042 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x, i %u.\n", hr
, i
);
2043 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
2044 color_key
.dwColorSpaceLowValue
, i
);
2045 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
2046 color_key
.dwColorSpaceHighValue
, i
);
2048 IDirectDrawSurface_Release(mipmap
);
2052 memset(&color_key
, 0, sizeof(color_key
));
2053 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2054 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2055 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2056 color_key
.dwColorSpaceLowValue
);
2057 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2058 color_key
.dwColorSpaceHighValue
);
2060 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2061 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
2062 IDirectDrawSurface_Release(mipmap
);
2063 refcount
= IDirectDrawSurface_Release(surface
);
2064 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2066 memset(&surface_desc
, 0, sizeof(surface_desc
));
2067 surface_desc
.dwSize
= sizeof(surface_desc
);
2068 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
2069 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
2070 surface_desc
.dwBackBufferCount
= 1;
2071 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2072 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2074 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2075 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2076 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2077 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2078 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2079 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2080 memset(&color_key
, 0, sizeof(color_key
));
2081 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2082 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2083 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2084 color_key
.dwColorSpaceLowValue
);
2085 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2086 color_key
.dwColorSpaceHighValue
);
2088 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
2089 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
2091 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2092 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2093 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2094 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2095 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2096 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2097 memset(&color_key
, 0, sizeof(color_key
));
2098 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2099 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2100 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2101 color_key
.dwColorSpaceLowValue
);
2102 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2103 color_key
.dwColorSpaceHighValue
);
2105 IDirectDrawSurface_Release(tmp
);
2107 refcount
= IDirectDrawSurface_Release(surface
);
2108 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2109 refcount
= IDirectDraw2_Release(ddraw
);
2110 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2111 DestroyWindow(window
);
2117 REFIID refcount_iid
;
2121 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
2122 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
2124 ULONG refcount
, expected_refcount
;
2125 IUnknown
*iface1
, *iface2
;
2129 for (i
= 0; i
< entry_count
; ++i
)
2131 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
2132 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
2135 for (j
= 0; j
< entry_count
; ++j
)
2137 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
2138 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
2141 expected_refcount
= 0;
2142 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
2143 ++expected_refcount
;
2144 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
2145 ++expected_refcount
;
2146 refcount
= IUnknown_Release(iface2
);
2147 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
2148 refcount
, test_name
, i
, j
, expected_refcount
);
2152 expected_refcount
= 0;
2153 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
2154 ++expected_refcount
;
2155 refcount
= IUnknown_Release(iface1
);
2156 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
2157 refcount
, test_name
, i
, expected_refcount
);
2162 static void test_surface_qi(void)
2164 static const struct qi_test tests
[] =
2166 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
2167 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
2168 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2169 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2170 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2171 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2172 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2173 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2174 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2175 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2176 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2177 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2178 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2179 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2180 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2181 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2182 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2183 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2184 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2185 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2186 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2187 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2188 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2189 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2190 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2191 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2192 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2193 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2194 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2195 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2196 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2197 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2198 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2199 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2200 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2201 {NULL
, NULL
, E_INVALIDARG
},
2204 IDirectDrawSurface
*surface
;
2205 DDSURFACEDESC surface_desc
;
2206 IDirect3DDevice2
*device
;
2207 IDirectDraw2
*ddraw
;
2211 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2213 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2217 window
= create_window();
2218 ddraw
= create_ddraw();
2219 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2220 /* Try to create a D3D device to see if the ddraw implementation supports
2221 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
2222 * doesn't support e.g. the IDirect3DTexture interfaces. */
2223 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2225 skip("Failed to create a 3D device, skipping test.\n");
2226 IDirectDraw2_Release(ddraw
);
2227 DestroyWindow(window
);
2230 IDirect3DDevice_Release(device
);
2232 memset(&surface_desc
, 0, sizeof(surface_desc
));
2233 surface_desc
.dwSize
= sizeof(surface_desc
);
2234 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2235 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2236 surface_desc
.dwWidth
= 512;
2237 surface_desc
.dwHeight
= 512;
2238 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, (IDirectDrawSurface
**)0xdeadbeef, NULL
);
2239 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
2240 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2241 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2243 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface
, tests
, ARRAY_SIZE(tests
));
2245 IDirectDrawSurface_Release(surface
);
2246 IDirectDraw2_Release(ddraw
);
2247 DestroyWindow(window
);
2250 static void test_device_qi(void)
2252 static const struct qi_test tests
[] =
2254 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
2255 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
2256 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
2257 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2258 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
2259 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
2260 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
2261 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
2262 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
2263 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
2264 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
2265 {&IID_IDirect3DDevice2
, &IID_IDirect3DDevice2
, S_OK
},
2266 {&IID_IDirect3DDevice
, &IID_IDirect3DDevice2
, S_OK
},
2267 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
2268 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
2269 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
2270 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
2271 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
2272 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
2273 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
2274 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
2275 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
2276 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
2277 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
2278 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
2279 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
2280 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
2281 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
2282 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
2283 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
2284 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
2285 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
2286 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
2287 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
2288 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
2289 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
2290 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
2291 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
2292 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
2293 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
2294 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
2295 {&IID_IUnknown
, &IID_IDirect3DDevice2
, S_OK
},
2298 IDirect3DDevice2
*device
;
2299 IDirectDraw2
*ddraw
;
2302 window
= create_window();
2303 ddraw
= create_ddraw();
2304 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2305 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2307 skip("Failed to create a 3D device, skipping test.\n");
2308 IDirectDraw2_Release(ddraw
);
2309 DestroyWindow(window
);
2313 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice2
, tests
, ARRAY_SIZE(tests
));
2315 IDirect3DDevice2_Release(device
);
2316 IDirectDraw2_Release(ddraw
);
2317 DestroyWindow(window
);
2320 static void test_wndproc(void)
2322 LONG_PTR proc
, ddraw_proc
;
2323 IDirectDraw2
*ddraw
;
2329 static struct message messages
[] =
2331 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2332 {WM_MOVE
, FALSE
, 0},
2333 {WM_SIZE
, FALSE
, 0},
2334 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2335 {WM_ACTIVATE
, FALSE
, 0},
2336 {WM_SETFOCUS
, FALSE
, 0},
2340 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2341 ddraw
= create_ddraw();
2342 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2344 wc
.lpfnWndProc
= test_proc
;
2345 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2346 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2348 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2349 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2351 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2352 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2353 (LONG_PTR
)test_proc
, proc
);
2354 expect_messages
= messages
;
2355 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2356 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2357 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2358 expect_messages
= NULL
;
2359 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2360 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2361 (LONG_PTR
)test_proc
, proc
);
2362 ref
= IDirectDraw2_Release(ddraw
);
2363 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2364 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2365 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2366 (LONG_PTR
)test_proc
, proc
);
2368 /* DDSCL_NORMAL doesn't. */
2369 ddraw
= create_ddraw();
2370 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2371 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2372 (LONG_PTR
)test_proc
, proc
);
2373 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2374 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2375 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2376 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2377 (LONG_PTR
)test_proc
, proc
);
2378 ref
= IDirectDraw2_Release(ddraw
);
2379 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2380 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2381 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2382 (LONG_PTR
)test_proc
, proc
);
2384 /* The original window proc is only restored by ddraw if the current
2385 * window proc matches the one ddraw set. This also affects switching
2386 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2387 ddraw
= create_ddraw();
2388 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2389 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2390 (LONG_PTR
)test_proc
, proc
);
2391 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2392 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2393 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2394 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2395 (LONG_PTR
)test_proc
, proc
);
2397 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2398 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2399 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2400 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2401 (LONG_PTR
)test_proc
, proc
);
2402 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2403 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2404 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2405 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2406 (LONG_PTR
)test_proc
, proc
);
2407 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2408 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2409 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2410 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2411 (LONG_PTR
)DefWindowProcA
, proc
);
2412 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2413 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2414 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, ddraw_proc
);
2415 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2416 (LONG_PTR
)DefWindowProcA
, proc
);
2417 ref
= IDirectDraw2_Release(ddraw
);
2418 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2419 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2420 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2421 (LONG_PTR
)test_proc
, proc
);
2423 ddraw
= create_ddraw();
2424 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2425 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2426 (LONG_PTR
)test_proc
, proc
);
2427 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2428 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2429 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2430 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2431 (LONG_PTR
)test_proc
, proc
);
2432 ref
= IDirectDraw2_Release(ddraw
);
2433 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2434 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2435 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2436 (LONG_PTR
)DefWindowProcA
, proc
);
2438 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2439 expect_messages
= NULL
;
2440 DestroyWindow(window
);
2441 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2444 static void test_window_style(void)
2446 LONG style
, exstyle
, tmp
, expected_style
;
2447 RECT fullscreen_rect
, r
;
2448 IDirectDraw2
*ddraw
;
2454 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2455 0, 0, 100, 100, 0, 0, 0, 0);
2456 ddraw
= create_ddraw();
2457 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2459 style
= GetWindowLongA(window
, GWL_STYLE
);
2460 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2461 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2463 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2464 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2466 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2467 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2468 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2469 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2471 GetWindowRect(window
, &r
);
2472 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2473 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2474 GetClientRect(window
, &r
);
2475 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2477 ret
= SetForegroundWindow(GetDesktopWindow());
2478 ok(ret
, "Failed to set foreground window.\n");
2480 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2481 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2482 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2483 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2485 ret
= SetForegroundWindow(window
);
2486 ok(ret
, "Failed to set foreground window.\n");
2487 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2488 * the next tests expect this. */
2489 ShowWindow(window
, SW_HIDE
);
2491 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2492 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2494 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2495 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2496 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2497 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2499 ShowWindow(window
, SW_SHOW
);
2500 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2501 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2503 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2504 expected_style
= style
| WS_VISIBLE
;
2505 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2506 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2507 expected_style
= exstyle
| WS_EX_TOPMOST
;
2508 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2510 ret
= SetForegroundWindow(GetDesktopWindow());
2511 ok(ret
, "Failed to set foreground window.\n");
2512 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2513 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
2514 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2515 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2516 expected_style
= exstyle
| WS_EX_TOPMOST
;
2517 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2519 ref
= IDirectDraw2_Release(ddraw
);
2520 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2522 DestroyWindow(window
);
2525 static void test_redundant_mode_set(void)
2527 DDSURFACEDESC surface_desc
= {0};
2528 IDirectDraw2
*ddraw
;
2534 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2535 0, 0, 100, 100, 0, 0, 0, 0);
2536 ddraw
= create_ddraw();
2537 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2539 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2540 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2542 surface_desc
.dwSize
= sizeof(surface_desc
);
2543 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
2544 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
2546 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2547 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2548 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2550 GetWindowRect(window
, &q
);
2554 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2555 GetWindowRect(window
, &s
);
2556 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2558 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2559 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2560 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2562 GetWindowRect(window
, &s
);
2563 ok(EqualRect(&r
, &s
) || broken(EqualRect(&q
, &s
) /* Windows 10 */),
2564 "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2566 ref
= IDirectDraw2_Release(ddraw
);
2567 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2569 DestroyWindow(window
);
2572 static SIZE screen_size
, screen_size2
;
2574 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2576 if (message
== WM_SIZE
)
2578 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2579 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2582 return test_proc(hwnd
, message
, wparam
, lparam
);
2585 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2587 if (message
== WM_SIZE
)
2589 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2590 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2593 return test_proc(hwnd
, message
, wparam
, lparam
);
2596 struct test_coop_level_mode_set_enum_param
2598 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
2601 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC
*surface_desc
, void *context
)
2603 struct test_coop_level_mode_set_enum_param
*param
= context
;
2605 if (U1(surface_desc
->ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
2606 return DDENUMRET_OK
;
2607 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
2608 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
2609 return DDENUMRET_OK
;
2611 if (!param
->ddraw_width
)
2613 param
->ddraw_width
= surface_desc
->dwWidth
;
2614 param
->ddraw_height
= surface_desc
->dwHeight
;
2615 return DDENUMRET_OK
;
2617 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
2618 return DDENUMRET_OK
;
2620 param
->user32_width
= surface_desc
->dwWidth
;
2621 param
->user32_height
= surface_desc
->dwHeight
;
2622 return DDENUMRET_CANCEL
;
2625 static void test_coop_level_mode_set(void)
2627 IDirectDrawSurface
*primary
;
2628 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
2629 IDirectDraw2
*ddraw
;
2632 HWND window
, window2
;
2636 struct test_coop_level_mode_set_enum_param param
;
2641 static const struct message exclusive_messages
[] =
2643 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2644 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2645 {WM_SIZE
, FALSE
, 0},
2646 {WM_DISPLAYCHANGE
, FALSE
, 0},
2649 static const struct message exclusive_focus_loss_messages
[] =
2651 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
},
2652 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Window resize due to mode change. */
2653 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2654 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* Generated by DefWindowProc. */
2655 {WM_DISPLAYCHANGE
, FALSE
, 0},
2656 {WM_KILLFOCUS
, FALSE
, 0},
2657 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Window minimized. */
2658 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
2659 * SW_MINIMIZED, causing a recursive window activation that does not
2660 * produce the same result in Wine yet. Ignore the difference for now.
2661 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
2662 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2663 {WM_MOVE
, FALSE
, 0},
2664 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2665 {WM_ACTIVATEAPP
, TRUE
, FALSE
},
2668 static const struct message exclusive_focus_restore_messages
[] =
2670 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
2671 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
2672 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
2673 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
2674 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
2675 /* Native redundantly sets the window size here. */
2676 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
2677 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
2678 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
2679 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
2682 static const struct message sc_restore_messages
[] =
2684 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
2685 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2686 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2687 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
2690 static const struct message sc_minimize_messages
[] =
2692 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
2693 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2694 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2695 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2698 static const struct message sc_maximize_messages
[] =
2700 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
2701 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2702 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2703 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
2707 static const struct message normal_messages
[] =
2709 {WM_DISPLAYCHANGE
, FALSE
, 0},
2713 ddraw
= create_ddraw();
2714 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2716 memset(¶m
, 0, sizeof(param
));
2717 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
2718 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#x.\n", hr
);
2719 ref
= IDirectDraw2_Release(ddraw
);
2720 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2722 if (!param
.user32_height
)
2724 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
2728 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2729 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
2730 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
2732 memset(&devmode
, 0, sizeof(devmode
));
2733 devmode
.dmSize
= sizeof(devmode
);
2734 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2735 devmode
.dmPelsWidth
= param
.user32_width
;
2736 devmode
.dmPelsHeight
= param
.user32_height
;
2737 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2738 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2740 ddraw
= create_ddraw();
2741 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2743 wc
.lpfnWndProc
= mode_set_proc
;
2744 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2745 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2746 wc
.lpfnWndProc
= mode_set_proc2
;
2747 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
2748 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2750 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2751 0, 0, 100, 100, 0, 0, 0, 0);
2752 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2753 0, 0, 100, 100, 0, 0, 0, 0);
2755 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2756 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2758 GetWindowRect(window
, &r
);
2759 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2760 wine_dbgstr_rect(&r
));
2762 memset(&ddsd
, 0, sizeof(ddsd
));
2763 ddsd
.dwSize
= sizeof(ddsd
);
2764 ddsd
.dwFlags
= DDSD_CAPS
;
2765 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2767 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2768 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2769 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2770 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2771 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2772 param
.user32_width
, ddsd
.dwWidth
);
2773 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2774 param
.user32_height
, ddsd
.dwHeight
);
2776 GetWindowRect(window
, &r
);
2777 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2778 wine_dbgstr_rect(&r
));
2780 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2781 expect_messages
= exclusive_messages
;
2785 hr
= IDirectDrawSurface_IsLost(primary
);
2786 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2787 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
2788 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2789 hr
= IDirectDrawSurface_IsLost(primary
);
2790 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2792 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2793 expect_messages
= NULL
;
2794 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
2795 "Expected screen size %ux%u, got %ux%u.\n",
2796 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
2798 GetWindowRect(window
, &r
);
2799 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2800 wine_dbgstr_rect(&r
));
2802 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2803 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2804 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2805 param
.user32_width
, ddsd
.dwWidth
);
2806 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2807 param
.user32_height
, ddsd
.dwHeight
);
2808 IDirectDrawSurface_Release(primary
);
2810 memset(&ddsd
, 0, sizeof(ddsd
));
2811 ddsd
.dwSize
= sizeof(ddsd
);
2812 ddsd
.dwFlags
= DDSD_CAPS
;
2813 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2815 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2816 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2817 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2818 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2819 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2820 param
.ddraw_width
, ddsd
.dwWidth
);
2821 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2822 param
.ddraw_height
, ddsd
.dwHeight
);
2824 GetWindowRect(window
, &r
);
2825 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2826 wine_dbgstr_rect(&r
));
2828 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2829 expect_messages
= exclusive_messages
;
2833 hr
= IDirectDrawSurface_IsLost(primary
);
2834 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2835 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2836 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2837 hr
= IDirectDrawSurface_IsLost(primary
);
2838 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2840 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2841 expect_messages
= NULL
;
2842 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
2843 "Expected screen size %ux%u, got %ux%u.\n",
2844 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
2846 GetWindowRect(window
, &r
);
2847 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2848 wine_dbgstr_rect(&r
));
2850 expect_messages
= exclusive_focus_loss_messages
;
2851 ret
= SetForegroundWindow(GetDesktopWindow());
2852 ok(ret
, "Failed to set foreground window.\n");
2853 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2854 memset(&devmode
, 0, sizeof(devmode
));
2855 devmode
.dmSize
= sizeof(devmode
);
2856 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2857 ok(ret
, "Failed to get display mode.\n");
2858 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
2859 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpect screen size %ux%u.\n",
2860 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2862 expect_messages
= exclusive_focus_restore_messages
;
2863 ShowWindow(window
, SW_RESTORE
);
2864 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2866 GetWindowRect(window
, &r
);
2867 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2868 wine_dbgstr_rect(&r
));
2869 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2870 ok(ret
, "Failed to get display mode.\n");
2871 ok(devmode
.dmPelsWidth
== param
.ddraw_width
2872 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpect screen size %ux%u.\n",
2873 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2875 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2876 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2877 /* Normally the primary should be restored here. Unfortunately this causes the
2878 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
2879 * testbot. Another Restore call would presumably avoid the crash, but it also moots
2880 * the point of the GetSurfaceDesc call. */
2882 expect_messages
= sc_minimize_messages
;
2883 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
2884 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2885 expect_messages
= NULL
;
2887 expect_messages
= sc_restore_messages
;
2888 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
2889 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2890 expect_messages
= NULL
;
2892 expect_messages
= sc_maximize_messages
;
2893 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
2894 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2895 expect_messages
= NULL
;
2897 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2898 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2900 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2901 expect_messages
= exclusive_messages
;
2905 hr
= IDirectDrawSurface_IsLost(primary
);
2906 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2907 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
2908 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2909 hr
= IDirectDrawSurface_IsLost(primary
);
2910 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2912 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2913 expect_messages
= NULL
;
2914 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
2915 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
2916 "Expected screen size %ux%u, got %ux%u.\n",
2917 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
2919 GetWindowRect(window
, &r
);
2920 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2921 wine_dbgstr_rect(&r
));
2923 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2924 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2925 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2926 param
.ddraw_width
, ddsd
.dwWidth
);
2927 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2928 param
.ddraw_height
, ddsd
.dwHeight
);
2929 IDirectDrawSurface_Release(primary
);
2932 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
2933 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2935 memset(&ddsd
, 0, sizeof(ddsd
));
2936 ddsd
.dwSize
= sizeof(ddsd
);
2937 ddsd
.dwFlags
= DDSD_CAPS
;
2938 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2940 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2941 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2942 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2943 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2944 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2945 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2946 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2947 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
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
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2954 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2956 GetWindowRect(window
, &r
);
2957 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2958 wine_dbgstr_rect(&r
));
2960 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2961 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2962 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2963 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2964 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2965 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2966 IDirectDrawSurface_Release(primary
);
2968 memset(&ddsd
, 0, sizeof(ddsd
));
2969 ddsd
.dwSize
= sizeof(ddsd
);
2970 ddsd
.dwFlags
= DDSD_CAPS
;
2971 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2973 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2974 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2975 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2976 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2977 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2978 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2979 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2980 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2982 GetWindowRect(window
, &r
);
2983 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2984 wine_dbgstr_rect(&r
));
2986 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2987 expect_messages
= normal_messages
;
2991 hr
= IDirectDrawSurface_IsLost(primary
);
2992 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2993 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2994 devmode
.dmPelsWidth
= param
.user32_width
;
2995 devmode
.dmPelsHeight
= param
.user32_height
;
2996 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2997 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2998 hr
= IDirectDrawSurface_IsLost(primary
);
2999 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3001 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3002 expect_messages
= NULL
;
3003 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3005 GetWindowRect(window
, &r
);
3006 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3007 wine_dbgstr_rect(&r
));
3009 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3010 expect_messages
= normal_messages
;
3014 hr
= IDirectDrawSurface_Restore(primary
);
3015 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3016 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3017 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3019 win_skip("Broken SetDisplayMode(), skipping remaining tests.\n");
3020 IDirectDrawSurface_Release(primary
);
3021 IDirectDraw2_Release(ddraw
);
3024 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3025 hr
= IDirectDrawSurface_Restore(primary
);
3026 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3027 hr
= IDirectDrawSurface_IsLost(primary
);
3028 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3030 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3031 expect_messages
= NULL
;
3032 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3034 GetWindowRect(window
, &r
);
3035 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3036 wine_dbgstr_rect(&r
));
3038 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3039 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3040 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3041 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3042 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3043 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3044 IDirectDrawSurface_Release(primary
);
3046 memset(&ddsd
, 0, sizeof(ddsd
));
3047 ddsd
.dwSize
= sizeof(ddsd
);
3048 ddsd
.dwFlags
= DDSD_CAPS
;
3049 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3051 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3052 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3053 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3054 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3055 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3056 param
.ddraw_width
, ddsd
.dwWidth
);
3057 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3058 param
.ddraw_height
, ddsd
.dwHeight
);
3060 GetWindowRect(window
, &r
);
3061 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3062 wine_dbgstr_rect(&r
));
3064 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3065 expect_messages
= normal_messages
;
3069 hr
= IDirectDrawSurface_IsLost(primary
);
3070 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3071 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
3072 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3073 hr
= IDirectDrawSurface_IsLost(primary
);
3074 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3076 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3077 expect_messages
= NULL
;
3078 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3080 GetWindowRect(window
, &r
);
3081 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3082 wine_dbgstr_rect(&r
));
3084 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3085 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3086 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3087 param
.ddraw_width
, ddsd
.dwWidth
);
3088 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3089 param
.ddraw_height
, ddsd
.dwHeight
);
3090 IDirectDrawSurface_Release(primary
);
3092 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3093 ok(ret
, "Failed to get display mode.\n");
3094 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3095 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3096 "Expected resolution %ux%u, got %ux%u.\n",
3097 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3098 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3099 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3100 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3102 memset(&ddsd
, 0, sizeof(ddsd
));
3103 ddsd
.dwSize
= sizeof(ddsd
);
3104 ddsd
.dwFlags
= DDSD_CAPS
;
3105 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3107 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3108 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3109 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3110 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3111 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3112 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3113 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3114 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3116 GetWindowRect(window
, &r
);
3117 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3118 wine_dbgstr_rect(&r
));
3120 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3121 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3122 * not DDSCL_FULLSCREEN. */
3123 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3124 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3126 GetWindowRect(window
, &r
);
3127 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3128 wine_dbgstr_rect(&r
));
3130 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3131 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3132 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3133 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3134 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3135 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3136 IDirectDrawSurface_Release(primary
);
3138 memset(&ddsd
, 0, sizeof(ddsd
));
3139 ddsd
.dwSize
= sizeof(ddsd
);
3140 ddsd
.dwFlags
= DDSD_CAPS
;
3141 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3143 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3144 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3145 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3146 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3147 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3148 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3149 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3150 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3152 GetWindowRect(window
, &r
);
3153 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3154 wine_dbgstr_rect(&r
));
3156 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3157 expect_messages
= normal_messages
;
3161 hr
= IDirectDrawSurface_IsLost(primary
);
3162 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3163 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3164 devmode
.dmPelsWidth
= param
.user32_width
;
3165 devmode
.dmPelsHeight
= param
.user32_height
;
3166 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3167 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3168 hr
= IDirectDrawSurface_IsLost(primary
);
3169 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3171 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3172 expect_messages
= NULL
;
3173 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3175 GetWindowRect(window
, &r
);
3176 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3177 wine_dbgstr_rect(&r
));
3179 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3180 expect_messages
= normal_messages
;
3184 hr
= IDirectDrawSurface_Restore(primary
);
3185 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3186 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3187 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3188 hr
= IDirectDrawSurface_Restore(primary
);
3189 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3190 hr
= IDirectDrawSurface_IsLost(primary
);
3191 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3193 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3194 expect_messages
= NULL
;
3195 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3197 GetWindowRect(window
, &r
);
3198 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3199 wine_dbgstr_rect(&r
));
3201 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3202 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3203 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3204 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3205 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3206 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3207 IDirectDrawSurface_Release(primary
);
3209 memset(&ddsd
, 0, sizeof(ddsd
));
3210 ddsd
.dwSize
= sizeof(ddsd
);
3211 ddsd
.dwFlags
= DDSD_CAPS
;
3212 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3214 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3215 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3216 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3217 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3218 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3219 param
.ddraw_width
, ddsd
.dwWidth
);
3220 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3221 param
.ddraw_height
, ddsd
.dwHeight
);
3223 GetWindowRect(window
, &r
);
3224 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3225 wine_dbgstr_rect(&r
));
3227 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3228 expect_messages
= normal_messages
;
3232 hr
= IDirectDrawSurface_IsLost(primary
);
3233 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3234 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3235 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3236 hr
= IDirectDrawSurface_IsLost(primary
);
3237 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3239 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3240 expect_messages
= NULL
;
3241 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3243 GetWindowRect(window
, &r
);
3244 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3245 wine_dbgstr_rect(&r
));
3247 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3248 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3249 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3250 param
.ddraw_width
, ddsd
.dwWidth
);
3251 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3252 param
.ddraw_height
, ddsd
.dwHeight
);
3253 IDirectDrawSurface_Release(primary
);
3255 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3256 ok(ret
, "Failed to get display mode.\n");
3257 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3258 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3259 "Expected resolution %ux%u, got %ux%u.\n",
3260 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3261 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3262 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3263 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3265 memset(&ddsd
, 0, sizeof(ddsd
));
3266 ddsd
.dwSize
= sizeof(ddsd
);
3267 ddsd
.dwFlags
= DDSD_CAPS
;
3268 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3270 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3271 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3272 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3273 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3274 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3275 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3276 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3277 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3278 IDirectDrawSurface_Release(primary
);
3280 GetWindowRect(window
, &r
);
3281 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3282 wine_dbgstr_rect(&r
));
3284 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
3285 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3286 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3287 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3288 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3290 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3291 expect_messages
= exclusive_messages
;
3295 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3296 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3298 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3299 expect_messages
= NULL
;
3300 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3301 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3302 "Expected screen size %ux%u, got %ux%u.\n",
3303 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3304 screen_size
.cx
, screen_size
.cy
);
3306 GetWindowRect(window
, &r
);
3307 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3308 wine_dbgstr_rect(&r
));
3310 memset(&ddsd
, 0, sizeof(ddsd
));
3311 ddsd
.dwSize
= sizeof(ddsd
);
3312 ddsd
.dwFlags
= DDSD_CAPS
;
3313 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3315 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3316 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3317 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3318 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3319 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3320 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3321 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3322 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3323 IDirectDrawSurface_Release(primary
);
3325 /* The screen restore is a property of DDSCL_EXCLUSIVE */
3326 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3327 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3328 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3329 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3331 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3332 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3334 memset(&ddsd
, 0, sizeof(ddsd
));
3335 ddsd
.dwSize
= sizeof(ddsd
);
3336 ddsd
.dwFlags
= DDSD_CAPS
;
3337 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3339 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3340 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3341 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3342 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3343 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3344 param
.ddraw_width
, ddsd
.dwWidth
);
3345 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3346 param
.ddraw_height
, ddsd
.dwHeight
);
3347 IDirectDrawSurface_Release(primary
);
3349 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3350 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3352 /* If the window is changed at the same time, messages are sent to the new window. */
3353 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3354 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3355 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3356 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3358 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3359 expect_messages
= exclusive_messages
;
3362 screen_size2
.cx
= 0;
3363 screen_size2
.cy
= 0;
3365 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3366 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3368 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3369 expect_messages
= NULL
;
3370 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n",
3371 screen_size
.cx
, screen_size
.cy
);
3372 ok(screen_size2
.cx
== registry_mode
.dmPelsWidth
&& screen_size2
.cy
== registry_mode
.dmPelsHeight
,
3373 "Expected screen size 2 %ux%u, got %ux%u.\n",
3374 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size2
.cx
, screen_size2
.cy
);
3376 GetWindowRect(window
, &r
);
3377 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3378 wine_dbgstr_rect(&r
));
3379 GetWindowRect(window2
, &r
);
3380 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3381 wine_dbgstr_rect(&r
));
3383 memset(&ddsd
, 0, sizeof(ddsd
));
3384 ddsd
.dwSize
= sizeof(ddsd
);
3385 ddsd
.dwFlags
= DDSD_CAPS
;
3386 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3388 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3389 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3390 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3391 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3392 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3393 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3394 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3395 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3396 IDirectDrawSurface_Release(primary
);
3398 ref
= IDirectDraw2_Release(ddraw
);
3399 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3401 GetWindowRect(window
, &r
);
3402 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3403 wine_dbgstr_rect(&r
));
3406 expect_messages
= NULL
;
3407 DestroyWindow(window
);
3408 DestroyWindow(window2
);
3409 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3410 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
3413 static void test_coop_level_mode_set_multi(void)
3415 IDirectDraw2
*ddraw1
, *ddraw2
;
3421 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3422 0, 0, 100, 100, 0, 0, 0, 0);
3423 ddraw1
= create_ddraw();
3424 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3426 /* With just a single ddraw object, the display mode is restored on
3428 hr
= set_display_mode(ddraw1
, 800, 600);
3429 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3431 win_skip("Broken SetDisplayMode(), skipping test.\n");
3432 IDirectDraw2_Release(ddraw1
);
3433 DestroyWindow(window
);
3436 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3437 w
= GetSystemMetrics(SM_CXSCREEN
);
3438 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3439 h
= GetSystemMetrics(SM_CYSCREEN
);
3440 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3442 ref
= IDirectDraw2_Release(ddraw1
);
3443 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3444 w
= GetSystemMetrics(SM_CXSCREEN
);
3445 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3446 h
= GetSystemMetrics(SM_CYSCREEN
);
3447 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3449 /* When there are multiple ddraw objects, the display mode is restored to
3450 * the initial mode, before the first SetDisplayMode() call. */
3451 ddraw1
= create_ddraw();
3452 hr
= set_display_mode(ddraw1
, 800, 600);
3453 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3454 w
= GetSystemMetrics(SM_CXSCREEN
);
3455 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3456 h
= GetSystemMetrics(SM_CYSCREEN
);
3457 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3459 ddraw2
= create_ddraw();
3460 hr
= set_display_mode(ddraw2
, 640, 480);
3461 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3462 w
= GetSystemMetrics(SM_CXSCREEN
);
3463 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3464 h
= GetSystemMetrics(SM_CYSCREEN
);
3465 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3467 ref
= IDirectDraw2_Release(ddraw2
);
3468 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3469 w
= GetSystemMetrics(SM_CXSCREEN
);
3470 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3471 h
= GetSystemMetrics(SM_CYSCREEN
);
3472 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3474 ref
= IDirectDraw2_Release(ddraw1
);
3475 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3476 w
= GetSystemMetrics(SM_CXSCREEN
);
3477 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3478 h
= GetSystemMetrics(SM_CYSCREEN
);
3479 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3481 /* Regardless of release ordering. */
3482 ddraw1
= create_ddraw();
3483 hr
= set_display_mode(ddraw1
, 800, 600);
3484 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3485 w
= GetSystemMetrics(SM_CXSCREEN
);
3486 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3487 h
= GetSystemMetrics(SM_CYSCREEN
);
3488 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3490 ddraw2
= create_ddraw();
3491 hr
= set_display_mode(ddraw2
, 640, 480);
3492 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3493 w
= GetSystemMetrics(SM_CXSCREEN
);
3494 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3495 h
= GetSystemMetrics(SM_CYSCREEN
);
3496 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3498 ref
= IDirectDraw2_Release(ddraw1
);
3499 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3500 w
= GetSystemMetrics(SM_CXSCREEN
);
3501 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3502 h
= GetSystemMetrics(SM_CYSCREEN
);
3503 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3505 ref
= IDirectDraw2_Release(ddraw2
);
3506 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3507 w
= GetSystemMetrics(SM_CXSCREEN
);
3508 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3509 h
= GetSystemMetrics(SM_CYSCREEN
);
3510 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3512 /* But only for ddraw objects that called SetDisplayMode(). */
3513 ddraw1
= create_ddraw();
3514 ddraw2
= create_ddraw();
3515 hr
= set_display_mode(ddraw2
, 640, 480);
3516 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3517 w
= GetSystemMetrics(SM_CXSCREEN
);
3518 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3519 h
= GetSystemMetrics(SM_CYSCREEN
);
3520 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3522 ref
= IDirectDraw2_Release(ddraw1
);
3523 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3524 w
= GetSystemMetrics(SM_CXSCREEN
);
3525 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3526 h
= GetSystemMetrics(SM_CYSCREEN
);
3527 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3529 ref
= IDirectDraw2_Release(ddraw2
);
3530 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3531 w
= GetSystemMetrics(SM_CXSCREEN
);
3532 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3533 h
= GetSystemMetrics(SM_CYSCREEN
);
3534 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3536 /* If there's a ddraw object that's currently in exclusive mode, it blocks
3537 * restoring the display mode. */
3538 ddraw1
= create_ddraw();
3539 hr
= set_display_mode(ddraw1
, 800, 600);
3540 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3541 w
= GetSystemMetrics(SM_CXSCREEN
);
3542 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3543 h
= GetSystemMetrics(SM_CYSCREEN
);
3544 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3546 ddraw2
= create_ddraw();
3547 hr
= set_display_mode(ddraw2
, 640, 480);
3548 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3549 w
= GetSystemMetrics(SM_CXSCREEN
);
3550 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3551 h
= GetSystemMetrics(SM_CYSCREEN
);
3552 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3554 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3555 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3557 ref
= IDirectDraw2_Release(ddraw1
);
3558 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3559 w
= GetSystemMetrics(SM_CXSCREEN
);
3560 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3561 h
= GetSystemMetrics(SM_CYSCREEN
);
3562 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3564 ref
= IDirectDraw2_Release(ddraw2
);
3565 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3566 w
= GetSystemMetrics(SM_CXSCREEN
);
3567 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3568 h
= GetSystemMetrics(SM_CYSCREEN
);
3569 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3571 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
3572 ddraw1
= create_ddraw();
3573 hr
= set_display_mode(ddraw1
, 800, 600);
3574 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3575 w
= GetSystemMetrics(SM_CXSCREEN
);
3576 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3577 h
= GetSystemMetrics(SM_CYSCREEN
);
3578 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3580 hr
= IDirectDraw2_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3581 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3583 ddraw2
= create_ddraw();
3584 hr
= set_display_mode(ddraw2
, 640, 480);
3585 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
3587 ref
= IDirectDraw2_Release(ddraw1
);
3588 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3589 w
= GetSystemMetrics(SM_CXSCREEN
);
3590 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3591 h
= GetSystemMetrics(SM_CYSCREEN
);
3592 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3594 ref
= IDirectDraw2_Release(ddraw2
);
3595 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3596 w
= GetSystemMetrics(SM_CXSCREEN
);
3597 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3598 h
= GetSystemMetrics(SM_CYSCREEN
);
3599 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3601 DestroyWindow(window
);
3604 static void test_initialize(void)
3606 IDirectDraw2
*ddraw
;
3609 ddraw
= create_ddraw();
3610 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3612 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
3613 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
3614 IDirectDraw2_Release(ddraw
);
3617 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw2
, (void **)&ddraw
);
3618 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr
);
3619 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
3620 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
3621 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
3622 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
3623 IDirectDraw2_Release(ddraw
);
3627 static void test_coop_level_surf_create(void)
3629 IDirectDrawSurface
*surface
;
3630 IDirectDraw2
*ddraw
;
3634 ddraw
= create_ddraw();
3635 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3637 memset(&ddsd
, 0, sizeof(ddsd
));
3638 ddsd
.dwSize
= sizeof(ddsd
);
3639 ddsd
.dwFlags
= DDSD_CAPS
;
3640 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3641 surface
= (void *)0xdeadbeef;
3642 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3643 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
3644 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
3646 surface
= (void *)0xdeadbeef;
3647 hr
= IDirectDraw2_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
3648 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
3649 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
3651 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3652 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3654 surface
= (void *)0xdeadbeef;
3655 hr
= IDirectDraw2_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
3656 ok(hr
== DDERR_INVALIDPARAMS
, "Unexpected hr %#x.\n", hr
);
3657 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
3659 IDirectDraw2_Release(ddraw
);
3662 static void test_coop_level_multi_window(void)
3664 HWND window1
, window2
;
3665 IDirectDraw2
*ddraw
;
3668 window1
= create_window();
3669 window2
= create_window();
3670 ddraw
= create_ddraw();
3671 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3673 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
3674 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3675 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3676 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3677 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
3678 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
3680 IDirectDraw2_Release(ddraw
);
3681 DestroyWindow(window2
);
3682 DestroyWindow(window1
);
3685 static void test_clear_rect_count(void)
3687 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3688 IDirect3DMaterial2
*white
, *red
, *green
, *blue
;
3689 IDirect3DViewport2
*viewport
;
3690 IDirect3DDevice2
*device
;
3691 IDirectDrawSurface
*rt
;
3692 IDirectDraw2
*ddraw
;
3697 window
= create_window();
3698 ddraw
= create_ddraw();
3699 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3700 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3702 skip("Failed to create a 3D device, skipping test.\n");
3703 IDirectDraw2_Release(ddraw
);
3704 DestroyWindow(window
);
3708 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
3709 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3711 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
3712 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
3713 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
3714 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
3716 viewport
= create_viewport(device
, 0, 0, 640, 480);
3717 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
3718 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
3720 viewport_set_background(device
, viewport
, white
);
3721 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
3722 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3723 viewport_set_background(device
, viewport
, red
);
3724 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
3725 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3726 viewport_set_background(device
, viewport
, green
);
3727 hr
= IDirect3DViewport2_Clear(viewport
, 0, NULL
, D3DCLEAR_TARGET
);
3728 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3729 viewport_set_background(device
, viewport
, blue
);
3730 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
3731 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3733 color
= get_surface_color(rt
, 320, 240);
3734 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x000000ff, 1)),
3735 "Got unexpected color 0x%08x.\n", color
);
3737 IDirectDrawSurface_Release(rt
);
3738 destroy_viewport(device
, viewport
);
3739 destroy_material(white
);
3740 destroy_material(red
);
3741 destroy_material(green
);
3742 destroy_material(blue
);
3743 IDirect3DDevice2_Release(device
);
3744 IDirectDraw2_Release(ddraw
);
3745 DestroyWindow(window
);
3748 static BOOL
test_mode_restored(IDirectDraw2
*ddraw
, HWND window
)
3750 DDSURFACEDESC ddsd1
, ddsd2
;
3753 memset(&ddsd1
, 0, sizeof(ddsd1
));
3754 ddsd1
.dwSize
= sizeof(ddsd1
);
3755 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd1
);
3756 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
3758 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3759 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3760 hr
= set_display_mode(ddraw
, 640, 480);
3761 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3762 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3763 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3765 memset(&ddsd2
, 0, sizeof(ddsd2
));
3766 ddsd2
.dwSize
= sizeof(ddsd2
);
3767 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd2
);
3768 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
3769 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3770 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3772 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
3775 static void test_coop_level_versions(void)
3781 IDirectDrawSurface
*surface
;
3782 IDirectDraw2
*ddraw2
;
3785 window
= create_window();
3786 ddraw2
= create_ddraw();
3787 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3788 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
3789 restored
= test_mode_restored(ddraw2
, window
);
3790 ok(restored
, "Display mode not restored in new ddraw object\n");
3792 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
3793 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3794 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3796 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3797 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
3798 restored
= test_mode_restored(ddraw2
, window
);
3799 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
3801 /* A successful one does */
3802 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3803 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3804 restored
= test_mode_restored(ddraw2
, window
);
3805 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
3807 IDirectDraw_Release(ddraw
);
3808 IDirectDraw2_Release(ddraw2
);
3810 ddraw2
= create_ddraw();
3811 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3812 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3813 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3815 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
3816 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3817 restored
= test_mode_restored(ddraw2
, window
);
3818 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
3820 IDirectDraw_Release(ddraw
);
3821 IDirectDraw2_Release(ddraw2
);
3823 /* A failing call does not restore the ddraw2+ behavior */
3824 ddraw2
= create_ddraw();
3825 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3826 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3827 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3829 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3830 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3831 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3832 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
3833 restored
= test_mode_restored(ddraw2
, window
);
3834 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
3836 IDirectDraw_Release(ddraw
);
3837 IDirectDraw2_Release(ddraw2
);
3839 /* Neither does a sequence of successful calls with the new interface */
3840 ddraw2
= create_ddraw();
3841 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3842 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3843 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3845 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3846 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3847 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
3848 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3849 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
3850 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3852 restored
= test_mode_restored(ddraw2
, window
);
3853 ok(!restored
, "Display mode restored after ddraw1-ddraw2 SetCooperativeLevel() call sequence\n");
3854 IDirectDraw_Release(ddraw
);
3855 IDirectDraw2_Release(ddraw2
);
3857 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
3858 ddraw2
= create_ddraw();
3859 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3860 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
3861 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
3863 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
3864 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3866 memset(&ddsd
, 0, sizeof(ddsd
));
3867 ddsd
.dwSize
= sizeof(ddsd
);
3868 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
3869 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
3870 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
3871 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3872 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#x.\n", hr
);
3873 IDirectDrawSurface_Release(surface
);
3874 restored
= test_mode_restored(ddraw2
, window
);
3875 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
3877 IDirectDraw_Release(ddraw
);
3878 IDirectDraw2_Release(ddraw2
);
3879 DestroyWindow(window
);
3882 static void test_lighting_interface_versions(void)
3884 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3885 IDirect3DMaterial2
*emissive
, *background
;
3886 IDirect3DViewport2
*viewport
;
3887 IDirect3DDevice2
*device
;
3888 IDirectDrawSurface
*rt
;
3889 IDirectDraw2
*ddraw
;
3893 D3DMATERIALHANDLE mat_handle
;
3897 static D3DVERTEX quad
[] =
3899 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3900 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3901 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3902 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
3904 static D3DLVERTEX lquad
[] =
3906 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3907 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3908 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3909 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
3911 static D3DTLVERTEX tlquad
[] =
3913 {{ 0.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3914 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3915 {{ 640.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3916 {{ 640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
3920 D3DVERTEXTYPE vertextype
;
3922 DWORD d3drs_lighting
, d3drs_specular
;
3928 /* Lighting is enabled when D3DVT_VERTEX is used and D3DDP_DONOTLIGHT is not
3929 * set. D3DVT_VERTEX has diffuse = 0xffffffff and specular = 0x00000000, as
3930 * in later d3d versions */
3931 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, 0, 0x0000ff00},
3932 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, 0, 0x0000ff00},
3933 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3934 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3935 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, 0, 0x0000ff00},
3936 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, 0, 0x0000ff00},
3937 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3938 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
3940 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, 0, 0x00ff0000},
3941 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, 0, 0x00ff0000},
3942 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
3943 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
3944 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, 0, 0x00ff8080},
3945 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, 0, 0x00ff8080},
3946 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
3947 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
3949 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, 0, 0x000000ff},
3950 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, 0, 0x000000ff},
3951 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
3952 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
3953 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, 0, 0x008080ff},
3954 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, 0, 0x008080ff},
3955 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
3956 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
3959 window
= create_window();
3960 ddraw
= create_ddraw();
3961 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3962 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3964 skip("Failed to create a 3D device, skipping test.\n");
3965 IDirectDraw2_Release(ddraw
);
3966 DestroyWindow(window
);
3970 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
3971 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3973 viewport
= create_viewport(device
, 0, 0, 640, 480);
3974 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
3975 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
3977 emissive
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
3978 hr
= IDirect3DMaterial2_GetHandle(emissive
, device
, &mat_handle
);
3979 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
3980 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
3981 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
3982 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
3983 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#x.\n", hr
);
3985 background
= create_diffuse_material(device
, 0.1f
, 0.1f
, 0.1f
, 0.1f
);
3986 viewport_set_background(device
, viewport
, background
);
3988 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, &rs
);
3989 ok(SUCCEEDED(hr
), "Failed to get specularenable render state, hr %#x.\n", hr
);
3990 ok(rs
== TRUE
, "Initial D3DRENDERSTATE_SPECULARENABLE is %#x, expected TRUE.\n", rs
);
3992 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
3994 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
3995 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3997 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, tests
[i
].d3drs_lighting
);
3998 ok(SUCCEEDED(hr
), "Failed to set lighting render state, hr %#x.\n", hr
);
3999 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
,
4000 tests
[i
].d3drs_specular
);
4001 ok(SUCCEEDED(hr
), "Failed to set specularenable render state, hr %#x.\n", hr
);
4003 hr
= IDirect3DDevice2_BeginScene(device
);
4004 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4005 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
4006 tests
[i
].vertextype
, tests
[i
].data
, 4, tests
[i
].draw_flags
| D3DDP_WAIT
);
4007 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4008 hr
= IDirect3DDevice2_EndScene(device
);
4009 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4011 color
= get_surface_color(rt
, 320, 240);
4012 ok(compare_color(color
, tests
[i
].color
, 1),
4013 "Got unexpected color 0x%08x, expected 0x%08x, test %u.\n",
4014 color
, tests
[i
].color
, i
);
4017 destroy_material(background
);
4018 destroy_material(emissive
);
4019 destroy_viewport(device
, viewport
);
4020 IDirectDrawSurface_Release(rt
);
4021 IDirect3DDevice2_Release(device
);
4022 ref
= IDirectDraw2_Release(ddraw
);
4023 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
4024 DestroyWindow(window
);
4030 IDirectDraw2
*ddraw
;
4033 } activateapp_testdata
;
4035 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
4037 if (message
== WM_ACTIVATEAPP
)
4039 if (activateapp_testdata
.ddraw
)
4042 activateapp_testdata
.received
= FALSE
;
4043 hr
= IDirectDraw2_SetCooperativeLevel(activateapp_testdata
.ddraw
,
4044 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
4045 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#x.\n", hr
);
4046 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
4048 activateapp_testdata
.received
= TRUE
;
4051 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
4054 static void test_coop_level_activateapp(void)
4056 IDirectDraw2
*ddraw
;
4061 IDirectDrawSurface
*surface
;
4063 ddraw
= create_ddraw();
4064 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4066 wc
.lpfnWndProc
= activateapp_test_proc
;
4067 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
4068 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
4070 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
4071 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
4073 /* Exclusive with window already active. */
4074 SetForegroundWindow(window
);
4075 activateapp_testdata
.received
= FALSE
;
4076 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4077 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4078 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
4079 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4080 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4082 /* Exclusive with window not active. */
4083 SetForegroundWindow(GetDesktopWindow());
4084 activateapp_testdata
.received
= FALSE
;
4085 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4086 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4087 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4088 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4089 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4091 /* Normal with window not active, then exclusive with the same window. */
4092 SetForegroundWindow(GetDesktopWindow());
4093 activateapp_testdata
.received
= FALSE
;
4094 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4095 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4096 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
4097 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4098 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4099 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4100 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4101 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4103 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
4104 SetForegroundWindow(GetDesktopWindow());
4105 activateapp_testdata
.received
= FALSE
;
4106 activateapp_testdata
.ddraw
= ddraw
;
4107 activateapp_testdata
.window
= window
;
4108 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
4109 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4110 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4111 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4112 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4113 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4115 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
4116 * succeeding. Another switch to exclusive and back to normal is needed to release the
4117 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
4118 * WM_ACTIVATEAPP messages. */
4119 activateapp_testdata
.ddraw
= NULL
;
4120 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4121 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4122 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4123 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4125 /* Setting DDSCL_NORMAL with recursive invocation. */
4126 SetForegroundWindow(GetDesktopWindow());
4127 activateapp_testdata
.received
= FALSE
;
4128 activateapp_testdata
.ddraw
= ddraw
;
4129 activateapp_testdata
.window
= window
;
4130 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
4131 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4132 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4133 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4135 /* DDraw is in exclusive mode now. */
4136 memset(&ddsd
, 0, sizeof(ddsd
));
4137 ddsd
.dwSize
= sizeof(ddsd
);
4138 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
4139 ddsd
.dwBackBufferCount
= 1;
4140 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
4141 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4142 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4143 IDirectDrawSurface_Release(surface
);
4145 /* Recover again, just to be sure. */
4146 activateapp_testdata
.ddraw
= NULL
;
4147 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4148 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4149 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4150 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4152 DestroyWindow(window
);
4153 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
4154 IDirectDraw2_Release(ddraw
);
4157 struct format_support_check
4159 const DDPIXELFORMAT
*format
;
4163 static HRESULT WINAPI
test_unsupported_formats_cb(DDSURFACEDESC
*desc
, void *ctx
)
4165 struct format_support_check
*format
= ctx
;
4167 if (!memcmp(format
->format
, &desc
->ddpfPixelFormat
, sizeof(*format
->format
)))
4169 format
->supported
= TRUE
;
4170 return DDENUMRET_CANCEL
;
4173 return DDENUMRET_OK
;
4176 static void test_unsupported_formats(void)
4179 BOOL expect_success
;
4181 IDirectDraw2
*ddraw
;
4182 IDirect3DDevice2
*device
;
4183 IDirectDrawSurface
*surface
;
4186 DWORD expected_caps
;
4197 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
4198 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
4204 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
4205 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
4209 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
4211 window
= create_window();
4212 ddraw
= create_ddraw();
4213 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4214 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4216 skip("Failed to create a 3D device, skipping test.\n");
4217 IDirectDraw2_Release(ddraw
);
4218 DestroyWindow(window
);
4222 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
4224 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
4225 hr
= IDirect3DDevice2_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
4226 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
4228 for (j
= 0; j
< ARRAY_SIZE(caps
); j
++)
4230 memset(&ddsd
, 0, sizeof(ddsd
));
4231 ddsd
.dwSize
= sizeof(ddsd
);
4232 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
4233 ddsd
.ddpfPixelFormat
= formats
[i
].fmt
;
4236 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
4238 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
4239 expect_success
= FALSE
;
4241 expect_success
= TRUE
;
4243 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4244 ok(SUCCEEDED(hr
) == expect_success
,
4245 "Got unexpected hr %#x for format %s, caps %#x, expected %s.\n",
4246 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
4250 memset(&ddsd
, 0, sizeof(ddsd
));
4251 ddsd
.dwSize
= sizeof(ddsd
);
4252 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &ddsd
);
4253 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4255 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
4256 expected_caps
= DDSCAPS_VIDEOMEMORY
;
4257 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
4258 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
4259 else if (check
.supported
)
4260 expected_caps
= DDSCAPS_VIDEOMEMORY
;
4262 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
4264 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
4265 "Expected capability %#x, format %s, input cap %#x.\n",
4266 expected_caps
, formats
[i
].name
, caps
[j
]);
4268 IDirectDrawSurface_Release(surface
);
4272 IDirect3DDevice2_Release(device
);
4273 IDirectDraw2_Release(ddraw
);
4274 DestroyWindow(window
);
4277 static void test_rt_caps(void)
4279 PALETTEENTRY palette_entries
[256];
4280 IDirectDrawPalette
*palette
;
4281 IDirect3DDevice2
*device
;
4282 IDirectDraw2
*ddraw
;
4290 static const DDPIXELFORMAT p8_fmt
=
4292 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
4293 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
4298 const DDPIXELFORMAT
*pf
;
4301 HRESULT create_device_hr
;
4303 HRESULT alternative_set_rt_hr
;
4304 BOOL create_may_fail
;
4310 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
4311 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4319 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4320 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4328 DDSCAPS_OFFSCREENPLAIN
,
4329 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4337 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4338 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4339 D3DERR_SURFACENOTINVIDMEM
,
4346 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4347 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4355 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
4356 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4365 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4374 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4382 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4383 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4384 D3DERR_SURFACENOTINVIDMEM
,
4391 DDSCAPS_SYSTEMMEMORY
,
4392 DDSCAPS_SYSTEMMEMORY
,
4401 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4409 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4411 DDERR_NOPALETTEATTACHED
,
4418 DDSCAPS_OFFSCREENPLAIN
,
4419 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
4427 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4428 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4429 DDERR_NOPALETTEATTACHED
,
4436 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4437 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4445 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
4446 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
4448 DDERR_INVALIDPIXELFORMAT
,
4450 TRUE
/* AMD Evergreen */,
4454 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
4455 ~0U /* AMD Evergreen */,
4457 DDERR_INVALIDPIXELFORMAT
,
4464 ~0U /* AMD Evergreen */,
4472 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
4473 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
4475 DDERR_INVALIDPIXELFORMAT
,
4476 DDERR_INVALIDPIXELFORMAT
,
4477 TRUE
/* Nvidia Kepler */,
4481 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
4482 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
4486 TRUE
/* Nvidia Kepler */,
4490 window
= create_window();
4491 ddraw
= create_ddraw();
4492 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4493 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4495 skip("Failed to create a 3D device, skipping test.\n");
4496 IDirectDraw2_Release(ddraw
);
4497 DestroyWindow(window
);
4500 z_depth
= get_device_z_depth(device
);
4501 ok(!!z_depth
, "Failed to get device z depth.\n");
4502 IDirect3DDevice2_Release(device
);
4504 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
4506 skip("D3D interface is not available, skipping test.\n");
4510 memset(palette_entries
, 0, sizeof(palette_entries
));
4511 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
4512 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
4514 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
4516 IDirectDrawSurface
*surface
, *rt
, *expected_rt
, *tmp
;
4517 DDSURFACEDESC surface_desc
;
4518 IDirect3DDevice2
*device
;
4520 memset(&surface_desc
, 0, sizeof(surface_desc
));
4521 surface_desc
.dwSize
= sizeof(surface_desc
);
4522 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4523 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
4524 if (test_data
[i
].pf
)
4526 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
4527 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
4529 if (test_data
[i
].caps_in
& DDSCAPS_ZBUFFER
)
4531 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4532 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
4534 surface_desc
.dwWidth
= 640;
4535 surface_desc
.dwHeight
= 480;
4536 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4537 ok(SUCCEEDED(hr
) || broken(test_data
[i
].create_may_fail
),
4538 "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
4539 i
, test_data
[i
].caps_in
, hr
);
4543 memset(&surface_desc
, 0, sizeof(surface_desc
));
4544 surface_desc
.dwSize
= sizeof(surface_desc
);
4545 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
4546 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
4547 ok(test_data
[i
].caps_out
== ~0U || surface_desc
.ddsCaps
.dwCaps
== test_data
[i
].caps_out
,
4548 "Test %u: Got unexpected caps %#x, expected %#x.\n",
4549 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
4551 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
4552 ok(hr
== test_data
[i
].create_device_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n",
4553 i
, hr
, test_data
[i
].create_device_hr
);
4556 if (hr
== DDERR_NOPALETTEATTACHED
)
4558 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
4559 ok(SUCCEEDED(hr
), "Test %u: Failed to set palette, hr %#x.\n", i
, hr
);
4560 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
4561 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
4562 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
4564 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
4566 IDirectDrawSurface_Release(surface
);
4568 memset(&surface_desc
, 0, sizeof(surface_desc
));
4569 surface_desc
.dwSize
= sizeof(surface_desc
);
4570 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4571 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
4572 surface_desc
.dwWidth
= 640;
4573 surface_desc
.dwHeight
= 480;
4574 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4575 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface, hr %#x.\n", i
, hr
);
4577 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
);
4578 ok(SUCCEEDED(hr
), "Test %u: Failed to create device, hr %#x.\n", i
, hr
);
4581 memset(&surface_desc
, 0, sizeof(surface_desc
));
4582 surface_desc
.dwSize
= sizeof(surface_desc
);
4583 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4584 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
4585 if (test_data
[i
].pf
)
4587 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
4588 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
4590 if (test_data
[i
].caps_in
& DDSCAPS_ZBUFFER
)
4592 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4593 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
4595 surface_desc
.dwWidth
= 640;
4596 surface_desc
.dwHeight
= 480;
4597 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
4598 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
4599 i
, test_data
[i
].caps_in
, hr
);
4601 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
4602 ok(hr
== test_data
[i
].set_rt_hr
|| broken(hr
== test_data
[i
].alternative_set_rt_hr
),
4603 "Test %u: Got unexpected hr %#x, expected %#x.\n",
4604 i
, hr
, test_data
[i
].set_rt_hr
);
4605 if (SUCCEEDED(hr
) || hr
== DDERR_INVALIDPIXELFORMAT
)
4608 expected_rt
= surface
;
4610 /* It appears the surface is set as render target in this case, but no
4611 * reference is taken. */
4612 if (hr
== DDERR_INVALIDPIXELFORMAT
)
4614 refcount
= IDirectDrawSurface_AddRef(rt
);
4615 ok(refcount
== 2, "Test %u: Got unexpected refcount %u.\n", i
, refcount
);
4618 hr
= IDirect3DDevice2_GetRenderTarget(device
, &tmp
);
4619 ok(SUCCEEDED(hr
), "Test %u: Failed to get render target, hr %#x.\n", i
, hr
);
4620 ok(tmp
== expected_rt
, "Test %u: Got unexpected rt %p.\n", i
, tmp
);
4622 IDirectDrawSurface_Release(tmp
);
4623 IDirectDrawSurface_Release(rt
);
4624 refcount
= IDirect3DDevice2_Release(device
);
4625 ok(refcount
== 0, "Test %u: The device was not properly freed, refcount %u.\n", i
, refcount
);
4626 refcount
= IDirectDrawSurface_Release(surface
);
4627 ok(refcount
== 0, "Test %u: The surface was not properly freed, refcount %u.\n", i
, refcount
);
4630 IDirectDrawPalette_Release(palette
);
4631 IDirect3D2_Release(d3d
);
4634 refcount
= IDirectDraw2_Release(ddraw
);
4635 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4636 DestroyWindow(window
);
4639 static void test_primary_caps(void)
4641 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
4642 IDirectDrawSurface
*surface
;
4643 DDSURFACEDESC surface_desc
;
4644 IDirectDraw2
*ddraw
;
4654 DWORD back_buffer_count
;
4662 DDSCAPS_PRIMARYSURFACE
,
4665 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
4669 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
4676 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
4683 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
4690 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
4697 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
4704 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4711 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4718 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4720 DDERR_NOEXCLUSIVEMODE
,
4724 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4725 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4731 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4732 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4735 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
4738 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4739 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
4745 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4746 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
4753 window
= create_window();
4754 ddraw
= create_ddraw();
4755 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4757 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
4759 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
4760 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4762 memset(&surface_desc
, 0, sizeof(surface_desc
));
4763 surface_desc
.dwSize
= sizeof(surface_desc
);
4764 surface_desc
.dwFlags
= DDSD_CAPS
;
4765 if (test_data
[i
].back_buffer_count
!= ~0u)
4766 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
4767 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
4768 surface_desc
.dwBackBufferCount
= test_data
[i
].back_buffer_count
;
4769 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4770 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
4774 memset(&surface_desc
, 0, sizeof(surface_desc
));
4775 surface_desc
.dwSize
= sizeof(surface_desc
);
4776 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
4777 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
4778 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
4779 "Test %u: Got unexpected caps %#x, expected %#x.\n",
4780 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
4782 IDirectDrawSurface_Release(surface
);
4785 refcount
= IDirectDraw2_Release(ddraw
);
4786 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4787 DestroyWindow(window
);
4790 static void test_surface_lock(void)
4792 IDirectDraw2
*ddraw
;
4793 IDirectDrawSurface
*surface
;
4794 IDirect3DDevice2
*device
;
4809 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
4810 "videomemory offscreenplain"
4813 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4814 "systemmemory offscreenplain"
4817 DDSCAPS_PRIMARYSURFACE
,
4821 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
4822 "videomemory texture"
4825 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
4826 "systemmemory texture"
4829 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4838 window
= create_window();
4839 ddraw
= create_ddraw();
4840 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4841 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4843 skip("Failed to create a 3D device, skipping test.\n");
4844 IDirectDraw2_Release(ddraw
);
4845 DestroyWindow(window
);
4848 z_depth
= get_device_z_depth(device
);
4849 ok(!!z_depth
, "Failed to get device z depth.\n");
4850 IDirect3DDevice2_Release(device
);
4852 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
4854 memset(&ddsd
, 0, sizeof(ddsd
));
4855 ddsd
.dwSize
= sizeof(ddsd
);
4856 ddsd
.dwFlags
= DDSD_CAPS
;
4857 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
4859 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
4863 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
4865 ddsd
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4866 U2(ddsd
).dwZBufferBitDepth
= z_depth
;
4868 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
4870 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4871 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4873 memset(&ddsd
, 0, sizeof(ddsd
));
4874 ddsd
.dwSize
= sizeof(ddsd
);
4875 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
4876 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4879 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4880 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4883 memset(&ddsd
, 0, sizeof(ddsd
));
4884 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
4885 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, tests
[i
].name
);
4887 IDirectDrawSurface_Release(surface
);
4890 refcount
= IDirectDraw2_Release(ddraw
);
4891 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4892 DestroyWindow(window
);
4895 static void test_surface_discard(void)
4897 IDirectDraw2
*ddraw
;
4898 IDirect3DDevice2
*device
;
4902 IDirectDrawSurface
*surface
, *target
;
4911 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, TRUE
},
4912 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
4913 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, TRUE
},
4914 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
4918 window
= create_window();
4919 ddraw
= create_ddraw();
4920 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4921 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4923 skip("Failed to create a 3D device, skipping test.\n");
4924 DestroyWindow(window
);
4925 IDirectDraw2_Release(ddraw
);
4929 hr
= IDirect3DDevice2_GetRenderTarget(device
, &target
);
4930 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4932 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
4936 memset(&ddsd
, 0, sizeof(ddsd
));
4937 ddsd
.dwSize
= sizeof(ddsd
);
4938 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4939 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
4942 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4945 skip("Failed to create surface, skipping.\n");
4949 memset(&ddsd
, 0, sizeof(ddsd
));
4950 ddsd
.dwSize
= sizeof(ddsd
);
4951 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
4952 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4953 addr
= ddsd
.lpSurface
;
4954 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4955 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4957 memset(&ddsd
, 0, sizeof(ddsd
));
4958 ddsd
.dwSize
= sizeof(ddsd
);
4959 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
4960 ok(SUCCEEDED(hr
) , "Failed to lock surface, hr %#x.\n", hr
);
4961 discarded
= ddsd
.lpSurface
!= addr
;
4962 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4963 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4965 hr
= IDirectDrawSurface_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
4966 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
4968 memset(&ddsd
, 0, sizeof(ddsd
));
4969 ddsd
.dwSize
= sizeof(ddsd
);
4970 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
4971 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4972 discarded
|= ddsd
.lpSurface
!= addr
;
4973 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4974 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4976 IDirectDrawSurface_Release(surface
);
4978 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
4979 * AMD r500, evergreen). Windows XP, at least on AMD r200, never changes the pointer. */
4980 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
4983 IDirectDrawSurface_Release(target
);
4984 IDirect3DDevice2_Release(device
);
4985 IDirectDraw2_Release(ddraw
);
4986 DestroyWindow(window
);
4989 static void fill_surface(IDirectDrawSurface
*surface
, D3DCOLOR color
)
4991 DDSURFACEDESC surface_desc
= {sizeof(surface_desc
)};
4996 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
4997 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4999 for (y
= 0; y
< surface_desc
.dwHeight
; ++y
)
5001 ptr
= (DWORD
*)((BYTE
*)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
);
5002 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
5008 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5009 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5012 static void test_flip(void)
5014 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
5015 IDirectDrawSurface
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
5016 DDSCAPS caps
= {DDSCAPS_FLIP
};
5017 DDSURFACEDESC surface_desc
;
5018 BOOL sysmem_primary
;
5019 IDirectDraw2
*ddraw
;
5020 DWORD expected_caps
;
5034 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
5035 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
5036 {"TEXTURE", DDSCAPS_TEXTURE
},
5039 window
= create_window();
5040 ddraw
= create_ddraw();
5041 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5043 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5044 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5046 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5048 /* Creating a flippable texture induces a BSoD on some versions of the
5049 * Intel graphics driver. At least Intel GMA 950 with driver version
5050 * 6.14.10.4926 on Windows XP SP3 is affected. */
5051 if ((test_data
[i
].caps
& DDSCAPS_TEXTURE
) && ddraw_is_intel(ddraw
))
5053 win_skip("Skipping flippable texture test.\n");
5057 memset(&surface_desc
, 0, sizeof(surface_desc
));
5058 surface_desc
.dwSize
= sizeof(surface_desc
);
5059 surface_desc
.dwFlags
= DDSD_CAPS
;
5060 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
5061 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
5062 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
5063 surface_desc
.dwWidth
= 512;
5064 surface_desc
.dwHeight
= 512;
5065 surface_desc
.dwBackBufferCount
= 3;
5066 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5067 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5069 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
5070 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
5071 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5072 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5074 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
5075 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
5076 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5077 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5079 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
5080 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5081 todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
5082 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
5086 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
5087 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
5088 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
5089 ok(hr
== DD_OK
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5090 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5091 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
5092 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5094 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5095 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5096 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
5097 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
5098 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5099 hr
= restore_surfaces(ddraw
);
5100 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#x.\n", test_data
[i
].name
, hr
);
5102 memset(&surface_desc
, 0, sizeof(surface_desc
));
5103 surface_desc
.dwSize
= sizeof(surface_desc
);
5104 hr
= IDirectDrawSurface_GetSurfaceDesc(frontbuffer
, &surface_desc
);
5105 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
5106 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
5107 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
5108 expected_caps
|= DDSCAPS_VISIBLE
;
5109 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5110 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5111 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
5113 hr
= IDirectDrawSurface_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
5114 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
5115 memset(&surface_desc
, 0, sizeof(surface_desc
));
5116 surface_desc
.dwSize
= sizeof(surface_desc
);
5117 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer1
, &surface_desc
);
5118 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
5119 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
5120 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5121 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
5122 expected_caps
|= DDSCAPS_BACKBUFFER
;
5123 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5124 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5126 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
5127 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
5128 memset(&surface_desc
, 0, sizeof(surface_desc
));
5129 surface_desc
.dwSize
= sizeof(surface_desc
);
5130 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer2
, &surface_desc
);
5131 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
5132 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
5133 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5134 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
5135 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5136 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5138 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
5139 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
5140 memset(&surface_desc
, 0, sizeof(surface_desc
));
5141 surface_desc
.dwSize
= sizeof(surface_desc
);
5142 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer3
, &surface_desc
);
5143 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
5144 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
5145 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5146 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5147 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5149 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
5150 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
5151 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
5152 test_data
[i
].name
, surface
, frontbuffer
);
5153 IDirectDrawSurface_Release(surface
);
5155 memset(&surface_desc
, 0, sizeof(surface_desc
));
5156 surface_desc
.dwSize
= sizeof(surface_desc
);
5157 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5158 surface_desc
.ddsCaps
.dwCaps
= 0;
5159 surface_desc
.dwWidth
= 640;
5160 surface_desc
.dwHeight
= 480;
5161 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5162 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
5163 hr
= IDirectDrawSurface_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
5164 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5165 IDirectDrawSurface_Release(surface
);
5167 hr
= IDirectDrawSurface_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
5168 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5169 hr
= IDirectDrawSurface_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
5170 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5171 hr
= IDirectDrawSurface_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
5172 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5173 hr
= IDirectDrawSurface_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
5174 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5176 /* The Nvidia Geforce 7 driver cannot do a color fill on a texture backbuffer after
5177 * the backbuffer has been locked or GetSurfaceDesc has been called. Do it ourselves
5178 * as a workaround. */
5179 fill_surface(backbuffer1
, 0xffff0000);
5180 fill_surface(backbuffer2
, 0xff00ff00);
5181 fill_surface(backbuffer3
, 0xff0000ff);
5183 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5184 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5185 color
= get_surface_color(backbuffer1
, 320, 240);
5186 /* The testbot seems to just copy the contents of one surface to all the
5187 * others, instead of properly flipping. */
5188 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
5189 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5190 color
= get_surface_color(backbuffer2
, 320, 240);
5191 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5192 fill_surface(backbuffer3
, 0xffff0000);
5194 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5195 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5196 color
= get_surface_color(backbuffer1
, 320, 240);
5197 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
5198 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5199 color
= get_surface_color(backbuffer2
, 320, 240);
5200 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5201 fill_surface(backbuffer3
, 0xff00ff00);
5203 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5204 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5205 color
= get_surface_color(backbuffer1
, 320, 240);
5206 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
5207 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5208 color
= get_surface_color(backbuffer2
, 320, 240);
5209 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5210 fill_surface(backbuffer3
, 0xff0000ff);
5212 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
5213 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5214 color
= get_surface_color(backbuffer2
, 320, 240);
5215 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
5216 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5217 color
= get_surface_color(backbuffer3
, 320, 240);
5218 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5219 fill_surface(backbuffer1
, 0xffff0000);
5221 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
5222 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5223 color
= get_surface_color(backbuffer1
, 320, 240);
5224 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5225 color
= get_surface_color(backbuffer3
, 320, 240);
5226 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
5227 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5228 fill_surface(backbuffer2
, 0xff00ff00);
5230 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
5231 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5232 color
= get_surface_color(backbuffer1
, 320, 240);
5233 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
5234 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5235 color
= get_surface_color(backbuffer2
, 320, 240);
5236 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5238 IDirectDrawSurface_Release(backbuffer3
);
5239 IDirectDrawSurface_Release(backbuffer2
);
5240 IDirectDrawSurface_Release(backbuffer1
);
5241 IDirectDrawSurface_Release(frontbuffer
);
5244 refcount
= IDirectDraw2_Release(ddraw
);
5245 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
5246 DestroyWindow(window
);
5249 static void reset_ddsd(DDSURFACEDESC
*ddsd
)
5251 memset(ddsd
, 0, sizeof(*ddsd
));
5252 ddsd
->dwSize
= sizeof(*ddsd
);
5255 static void test_set_surface_desc(void)
5257 IDirectDraw2
*ddraw
;
5261 IDirectDrawSurface
*surface
;
5262 IDirectDrawSurface3
*surface3
;
5272 invalid_caps_tests
[] =
5274 {DDSCAPS_VIDEOMEMORY
, FALSE
, "videomemory plain"},
5275 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, TRUE
, "systemmemory texture"},
5276 {DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
, FALSE
, "systemmemory primary"},
5279 window
= create_window();
5280 ddraw
= create_ddraw();
5281 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5282 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5283 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5286 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
5289 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5290 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5291 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5292 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5293 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5294 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5295 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5297 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5298 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5300 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
5301 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
5302 IDirectDrawSurface_Release(surface
);
5305 ddsd
.dwFlags
= DDSD_LPSURFACE
;
5306 ddsd
.lpSurface
= data
;
5307 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5308 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5310 /* Redundantly setting the same lpSurface is not an error. */
5311 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5312 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5313 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5314 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5315 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
5316 ok(ddsd
.lpSurface
== NULL
, "lpSurface is %p, expected NULL.\n", ddsd
.lpSurface
);
5318 hr
= IDirectDrawSurface3_Lock(surface3
, NULL
, &ddsd
, 0, NULL
);
5319 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
5320 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
5321 ok(ddsd
.lpSurface
== data
, "lpSurface is %p, expected %p.\n", data
, data
);
5322 hr
= IDirectDrawSurface3_Unlock(surface3
, NULL
);
5323 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5326 ddsd
.dwFlags
= DDSD_LPSURFACE
;
5327 ddsd
.lpSurface
= data
;
5328 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 1);
5329 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with flags=1 returned %#x.\n", hr
);
5331 ddsd
.lpSurface
= NULL
;
5332 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5333 ok(hr
== DDERR_INVALIDPARAMS
, "Setting lpSurface=NULL returned %#x.\n", hr
);
5335 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, NULL
, 0);
5336 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with NULL desc returned %#x.\n", hr
);
5338 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5339 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5340 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
5341 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
5343 /* Setting the caps is an error. This also means the original description cannot be reapplied. */
5344 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5345 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the original desc returned %#x.\n", hr
);
5347 ddsd
.dwFlags
= DDSD_CAPS
;
5348 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5349 ok(hr
== DDERR_INVALIDPARAMS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
5351 /* dwCaps = 0 is allowed, but ignored. */
5352 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_LPSURFACE
;
5353 ddsd
.lpSurface
= data
;
5354 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5355 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
5356 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5357 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5358 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
5359 ddsd
.ddsCaps
.dwCaps
= 0;
5360 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5361 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5363 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5364 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5365 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
5366 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
5368 /* Setting the height is allowed, but it cannot be set to 0, and only if LPSURFACE is set too. */
5370 ddsd
.dwFlags
= DDSD_HEIGHT
;
5372 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5373 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height without lpSurface returned %#x.\n", hr
);
5375 ddsd
.lpSurface
= data
;
5376 ddsd
.dwFlags
= DDSD_HEIGHT
| DDSD_LPSURFACE
;
5377 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5378 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5381 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5382 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height=0 returned %#x.\n", hr
);
5385 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5386 ok(SUCCEEDED(hr
), "GetSurfaceDesc failed, hr %#x.\n", hr
);
5387 ok(ddsd
.dwWidth
== 8, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
5388 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
5390 /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0. */
5392 ddsd
.dwFlags
= DDSD_PITCH
;
5393 U1(ddsd
).lPitch
= 8 * 4;
5394 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5395 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch without lpSurface or width returned %#x.\n", hr
);
5397 ddsd
.dwFlags
= DDSD_WIDTH
;
5399 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5400 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width without lpSurface or pitch returned %#x.\n", hr
);
5402 ddsd
.dwFlags
= DDSD_PITCH
| DDSD_LPSURFACE
;
5403 ddsd
.lpSurface
= data
;
5404 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5405 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch and lpSurface without width returned %#x.\n", hr
);
5407 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_LPSURFACE
;
5408 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5409 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width and lpSurface without pitch returned %#x.\n", hr
);
5411 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
5412 U1(ddsd
).lPitch
= 16 * 4;
5414 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5415 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5418 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5419 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5420 ok(ddsd
.dwWidth
== 16, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
5421 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
5422 ok(U1(ddsd
).lPitch
== 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %u.\n", U1(ddsd
).lPitch
);
5424 /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise.
5426 * VMware rejects those calls, but all real drivers accept it. Mark the VMware behavior broken. */
5427 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
5428 U1(ddsd
).lPitch
= 4 * 4;
5429 ddsd
.lpSurface
= data
;
5430 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5431 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
5433 U1(ddsd
).lPitch
= 4;
5434 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5435 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
5437 U1(ddsd
).lPitch
= 16 * 4 + 1;
5438 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5439 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
5441 U1(ddsd
).lPitch
= 16 * 4 + 3;
5442 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5443 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
5445 U1(ddsd
).lPitch
= -4;
5446 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5447 ok(hr
== DDERR_INVALIDPARAMS
, "Setting negative pitch returned %#x.\n", hr
);
5449 U1(ddsd
).lPitch
= 16 * 4;
5450 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5451 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5454 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
5455 U1(ddsd
).lPitch
= 0;
5457 ddsd
.lpSurface
= data
;
5458 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5459 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero pitch returned %#x.\n", hr
);
5461 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
5462 U1(ddsd
).lPitch
= 16 * 4;
5464 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5465 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero width returned %#x.\n", hr
);
5467 /* Setting the pixelformat without LPSURFACE is an error, but with LPSURFACE it works. */
5468 ddsd
.dwFlags
= DDSD_PIXELFORMAT
;
5469 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5470 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5471 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5472 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5473 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5474 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5475 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5476 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the pixel format returned %#x.\n", hr
);
5478 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
5479 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5480 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5482 /* Can't set color keys. */
5484 ddsd
.dwFlags
= DDSD_CKSRCBLT
;
5485 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff0000;
5486 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff0000;
5487 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5488 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
5490 ddsd
.dwFlags
= DDSD_CKSRCBLT
| DDSD_LPSURFACE
;
5491 ddsd
.lpSurface
= data
;
5492 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5493 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
5495 IDirectDrawSurface3_Release(surface3
);
5497 /* SetSurfaceDesc needs systemmemory surfaces.
5499 * As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing DDSD_LINEARSIZE is moot. */
5500 for (i
= 0; i
< ARRAY_SIZE(invalid_caps_tests
); i
++)
5503 ddsd
.dwFlags
= DDSD_CAPS
;
5504 ddsd
.ddsCaps
.dwCaps
= invalid_caps_tests
[i
].caps
;
5505 if (!(invalid_caps_tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
5507 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5510 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5511 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5512 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5513 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5514 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5515 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5518 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5519 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
, "Failed to create surface, hr %#x.\n", hr
);
5522 skip("Cannot create a %s surface, skipping vidmem SetSurfaceDesc test.\n",
5523 invalid_caps_tests
[i
].name
);
5526 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
5527 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
5528 IDirectDrawSurface_Release(surface
);
5531 ddsd
.dwFlags
= DDSD_LPSURFACE
;
5532 ddsd
.lpSurface
= data
;
5533 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5534 if (invalid_caps_tests
[i
].supported
)
5536 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5540 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
5541 invalid_caps_tests
[i
].name
, hr
);
5543 /* Check priority of error conditions. */
5544 ddsd
.dwFlags
= DDSD_WIDTH
;
5545 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5546 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
5547 invalid_caps_tests
[i
].name
, hr
);
5550 IDirectDrawSurface3_Release(surface3
);
5554 ref
= IDirectDraw2_Release(ddraw
);
5555 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
5556 DestroyWindow(window
);
5559 static void test_user_memory_getdc(void)
5561 IDirectDraw2
*ddraw
;
5565 IDirectDrawSurface
*surface
;
5566 IDirectDrawSurface3
*surface3
;
5575 window
= create_window();
5576 ddraw
= create_ddraw();
5577 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5579 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5580 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5583 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
5586 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5587 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5588 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5589 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5590 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5591 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5592 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5593 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5594 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5596 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
5597 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
5598 IDirectDrawSurface_Release(surface
);
5600 memset(data
, 0xaa, sizeof(data
));
5602 ddsd
.dwFlags
= DDSD_LPSURFACE
;
5603 ddsd
.lpSurface
= data
;
5604 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5605 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5607 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
5608 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
5609 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
5610 ok(!!bitmap
, "Failed to get bitmap.\n");
5611 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
5612 ok(size
== sizeof(dib
), "Got unexpected size %d.\n", size
);
5613 ok(dib
.dsBm
.bmBits
== data
, "Got unexpected bits %p, expected %p.\n", dib
.dsBm
.bmBits
, data
);
5614 BitBlt(dc
, 0, 0, 16, 8, NULL
, 0, 0, WHITENESS
);
5615 BitBlt(dc
, 0, 8, 16, 8, NULL
, 0, 0, BLACKNESS
);
5616 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
5617 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
5619 ok(data
[0][0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data
[0][0]);
5620 ok(data
[15][15] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data
[15][15]);
5622 ddsd
.dwFlags
= DDSD_LPSURFACE
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
;
5623 ddsd
.lpSurface
= data
;
5626 U1(ddsd
).lPitch
= sizeof(*data
);
5627 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5628 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5630 memset(data
, 0xaa, sizeof(data
));
5631 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
5632 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
5633 BitBlt(dc
, 0, 0, 4, 8, NULL
, 0, 0, BLACKNESS
);
5634 BitBlt(dc
, 1, 1, 2, 2, NULL
, 0, 0, WHITENESS
);
5635 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
5636 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
5638 for (y
= 0; y
< 4; y
++)
5640 for (x
= 0; x
< 4; x
++)
5642 if ((x
== 1 || x
== 2) && (y
== 1 || y
== 2))
5643 ok(data
[y
][x
] == 0xffffffff, "Expected color 0xffffffff on position %ux%u, got %#x.\n",
5646 ok(data
[y
][x
] == 0x00000000, "Expected color 0xaaaaaaaa on position %ux%u, got %#x.\n",
5650 ok(data
[0][5] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 5x0, got %#x.\n",
5652 ok(data
[7][3] == 0x00000000, "Expected color 0x00000000 on position 3x7, got %#x.\n",
5654 ok(data
[7][4] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 4x7, got %#x.\n",
5656 ok(data
[8][0] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 0x8, got %#x.\n",
5659 IDirectDrawSurface3_Release(surface3
);
5660 ref
= IDirectDraw2_Release(ddraw
);
5661 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
5662 DestroyWindow(window
);
5665 static void test_sysmem_overlay(void)
5667 IDirectDraw2
*ddraw
;
5671 IDirectDrawSurface
*surface
;
5674 window
= create_window();
5675 ddraw
= create_ddraw();
5676 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5678 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5679 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5682 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
5685 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
5686 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5687 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5688 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5689 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5690 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5691 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5692 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5693 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#x.\n", hr
);
5695 ref
= IDirectDraw2_Release(ddraw
);
5696 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
5697 DestroyWindow(window
);
5700 static void test_primary_palette(void)
5702 DDSCAPS surface_caps
= {DDSCAPS_FLIP
};
5703 IDirectDrawSurface
*primary
, *backbuffer
;
5704 PALETTEENTRY palette_entries
[256];
5705 IDirectDrawPalette
*palette
, *tmp
;
5706 DDSURFACEDESC surface_desc
;
5707 IDirectDraw2
*ddraw
;
5713 window
= create_window();
5714 ddraw
= create_ddraw();
5715 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5716 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
5718 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
5719 IDirectDraw2_Release(ddraw
);
5720 DestroyWindow(window
);
5723 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5724 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5726 memset(&surface_desc
, 0, sizeof(surface_desc
));
5727 surface_desc
.dwSize
= sizeof(surface_desc
);
5728 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
5729 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
5730 surface_desc
.dwBackBufferCount
= 1;
5731 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
5732 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5733 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
5734 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
5736 memset(palette_entries
, 0, sizeof(palette_entries
));
5737 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
5738 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
5739 refcount
= get_refcount((IUnknown
*)palette
);
5740 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5742 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5743 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
5744 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
5746 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
5747 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5749 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
5750 * and is generally somewhat broken with respect to 8 bpp / palette
5752 if (SUCCEEDED(IDirectDrawSurface_GetPalette(backbuffer
, &tmp
)))
5754 win_skip("Broken palette handling detected, skipping tests.\n");
5755 IDirectDrawPalette_Release(tmp
);
5756 IDirectDrawPalette_Release(palette
);
5757 /* The Windows 8 testbot keeps extra references to the primary and
5758 * backbuffer while in 8 bpp mode. */
5759 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
5760 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
5764 refcount
= get_refcount((IUnknown
*)palette
);
5765 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5767 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5768 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
5769 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
5770 "Got unexpected palette caps %#x.\n", palette_caps
);
5772 hr
= IDirectDrawSurface_SetPalette(primary
, NULL
);
5773 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5774 refcount
= get_refcount((IUnknown
*)palette
);
5775 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5777 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5778 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
5779 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
5781 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
5782 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5783 refcount
= get_refcount((IUnknown
*)palette
);
5784 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
5786 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
5787 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
5788 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
5789 IDirectDrawPalette_Release(tmp
);
5790 hr
= IDirectDrawSurface_GetPalette(backbuffer
, &tmp
);
5791 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
5793 refcount
= IDirectDrawPalette_Release(palette
);
5794 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5795 refcount
= IDirectDrawPalette_Release(palette
);
5796 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5798 /* Note that this only seems to work when the palette is attached to the
5799 * primary surface. When attached to a regular surface, attempting to get
5800 * the palette here will cause an access violation. */
5801 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
5802 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
5804 hr
= IDirectDrawSurface_IsLost(primary
);
5805 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
5807 memset(&surface_desc
, 0, sizeof(surface_desc
));
5808 surface_desc
.dwSize
= sizeof(surface_desc
);
5809 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
5810 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5811 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
5812 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
5813 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 8, "Got unexpected bit count %u.\n",
5814 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
5816 hr
= set_display_mode(ddraw
, 640, 480);
5817 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
5819 memset(&surface_desc
, 0, sizeof(surface_desc
));
5820 surface_desc
.dwSize
= sizeof(surface_desc
);
5821 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
5822 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5823 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
5824 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
5825 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 32
5826 || U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 24,
5827 "Got unexpected bit count %u.\n", U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
5829 hr
= IDirectDrawSurface_IsLost(primary
);
5830 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
5831 hr
= IDirectDrawSurface_Restore(primary
);
5832 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
5833 hr
= IDirectDrawSurface_IsLost(primary
);
5834 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
5836 memset(&surface_desc
, 0, sizeof(surface_desc
));
5837 surface_desc
.dwSize
= sizeof(surface_desc
);
5838 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
5839 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5840 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
5841 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
5842 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 32
5843 || U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 24,
5844 "Got unexpected bit count %u.\n", U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
5847 refcount
= IDirectDrawSurface_Release(backbuffer
);
5848 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
5849 refcount
= IDirectDrawSurface_Release(primary
);
5850 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5851 refcount
= IDirectDraw2_Release(ddraw
);
5852 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5853 DestroyWindow(window
);
5856 static HRESULT WINAPI
surface_counter(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
5858 UINT
*surface_count
= context
;
5861 IDirectDrawSurface_Release(surface
);
5863 return DDENUMRET_OK
;
5866 static void test_surface_attachment(void)
5868 IDirectDrawSurface
*surface1
, *surface2
, *surface3
, *surface4
;
5869 DDSCAPS caps
= {DDSCAPS_TEXTURE
};
5870 DDSURFACEDESC surface_desc
;
5871 IDirectDraw2
*ddraw
;
5877 window
= create_window();
5878 ddraw
= create_ddraw();
5879 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5880 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5881 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5883 memset(&surface_desc
, 0, sizeof(surface_desc
));
5884 surface_desc
.dwSize
= sizeof(surface_desc
);
5885 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
5886 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
5887 U2(surface_desc
).dwMipMapCount
= 3;
5888 surface_desc
.dwWidth
= 128;
5889 surface_desc
.dwHeight
= 128;
5890 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5891 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5893 hr
= IDirectDrawSurface_GetAttachedSurface(surface1
, &caps
, &surface2
);
5894 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
5895 hr
= IDirectDrawSurface_GetAttachedSurface(surface2
, &caps
, &surface3
);
5896 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
5897 hr
= IDirectDrawSurface_GetAttachedSurface(surface3
, &caps
, &surface4
);
5898 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
5901 IDirectDrawSurface_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
5902 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
5904 IDirectDrawSurface_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
5905 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
5907 IDirectDrawSurface_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
5908 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
5910 memset(&surface_desc
, 0, sizeof(surface_desc
));
5911 surface_desc
.dwSize
= sizeof(surface_desc
);
5912 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5913 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5914 surface_desc
.dwWidth
= 16;
5915 surface_desc
.dwHeight
= 16;
5916 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5917 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5919 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
5920 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5921 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5922 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5923 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
5924 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5925 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
5926 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5927 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
5928 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5929 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
5930 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5932 IDirectDrawSurface_Release(surface4
);
5934 memset(&surface_desc
, 0, sizeof(surface_desc
));
5935 surface_desc
.dwSize
= sizeof(surface_desc
);
5936 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5937 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5938 surface_desc
.dwWidth
= 16;
5939 surface_desc
.dwHeight
= 16;
5940 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5941 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5943 if (SUCCEEDED(hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
)))
5945 skip("Running on refrast, skipping some tests.\n");
5946 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface4
);
5947 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
5951 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5952 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5953 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5954 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
5955 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5956 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
5957 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5958 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
5959 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5960 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
5961 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
5964 IDirectDrawSurface_Release(surface4
);
5965 IDirectDrawSurface_Release(surface3
);
5966 IDirectDrawSurface_Release(surface2
);
5967 IDirectDrawSurface_Release(surface1
);
5969 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5970 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5972 /* Try a single primary and two offscreen plain surfaces. */
5973 memset(&surface_desc
, 0, sizeof(surface_desc
));
5974 surface_desc
.dwSize
= sizeof(surface_desc
);
5975 surface_desc
.dwFlags
= DDSD_CAPS
;
5976 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
5977 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5978 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5980 memset(&surface_desc
, 0, sizeof(surface_desc
));
5981 surface_desc
.dwSize
= sizeof(surface_desc
);
5982 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5983 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5984 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
5985 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
5986 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
5987 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5989 memset(&surface_desc
, 0, sizeof(surface_desc
));
5990 surface_desc
.dwSize
= sizeof(surface_desc
);
5991 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5992 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5993 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
5994 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
5995 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
5996 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5998 /* This one has a different size. */
5999 memset(&surface_desc
, 0, sizeof(surface_desc
));
6000 surface_desc
.dwSize
= sizeof(surface_desc
);
6001 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6002 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6003 surface_desc
.dwWidth
= 128;
6004 surface_desc
.dwHeight
= 128;
6005 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
6006 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6008 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6009 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
6010 /* Try the reverse without detaching first. */
6011 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
6012 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
6013 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
6014 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
6016 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
6017 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
6018 /* Try to detach reversed. */
6019 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
6020 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6021 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface1
);
6022 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
6024 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface3
);
6025 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
6026 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface3
);
6027 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
6029 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
6030 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6031 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
6032 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6034 IDirectDrawSurface_Release(surface4
);
6035 IDirectDrawSurface_Release(surface3
);
6036 IDirectDrawSurface_Release(surface2
);
6037 IDirectDrawSurface_Release(surface1
);
6039 /* Test depth surfaces of different sizes. */
6040 memset(&surface_desc
, 0, sizeof(surface_desc
));
6041 surface_desc
.dwSize
= sizeof(surface_desc
);
6042 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6043 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
6044 surface_desc
.dwWidth
= 64;
6045 surface_desc
.dwHeight
= 64;
6046 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6047 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
6049 memset(&surface_desc
, 0, sizeof(surface_desc
));
6050 surface_desc
.dwSize
= sizeof(surface_desc
);
6051 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
6052 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
6053 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6054 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
6055 U1(surface_desc
.ddpfPixelFormat
).dwZBufferBitDepth
= 16;
6056 U3(surface_desc
.ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
6057 surface_desc
.dwWidth
= 32;
6058 surface_desc
.dwHeight
= 32;
6059 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
6060 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
6061 surface_desc
.dwWidth
= 64;
6062 surface_desc
.dwHeight
= 64;
6063 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
6064 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
6065 surface_desc
.dwWidth
= 128;
6066 surface_desc
.dwHeight
= 128;
6067 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
6068 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
6070 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6071 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6073 IDirectDrawSurface2_DeleteAttachedSurface(surface1
, 0, surface3
);
6074 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface3
);
6075 ok(hr
== D3D_OK
, "Failed to attach depth buffer, hr %#x.\n", hr
);
6076 hr
= IDirectDrawSurface2_DeleteAttachedSurface(surface1
, 0, surface3
);
6077 ok(hr
== D3D_OK
, "Failed to detach depth buffer, hr %#x.\n", hr
);
6078 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
6079 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6081 IDirectDrawSurface2_Release(surface4
);
6082 IDirectDrawSurface2_Release(surface3
);
6083 IDirectDrawSurface2_Release(surface2
);
6084 IDirectDrawSurface2_Release(surface1
);
6086 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
6087 memset(&surface_desc
, 0, sizeof(surface_desc
));
6088 surface_desc
.dwSize
= sizeof(surface_desc
);
6089 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6090 surface_desc
.dwWidth
= 64;
6091 surface_desc
.dwHeight
= 64;
6092 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
6093 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6094 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
6095 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
6096 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
6097 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
6098 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
6099 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6100 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6101 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
6102 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6104 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
6105 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
6106 U1(surface_desc
.ddpfPixelFormat
).dwZBufferBitDepth
= 16;
6107 U3(surface_desc
.ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
6108 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
6109 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6111 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6112 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
6113 refcount
= get_refcount((IUnknown
*)surface2
);
6114 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
6115 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6116 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
6118 /* Attaching while already attached to other surface. */
6119 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface2
);
6120 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
6121 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface3
, 0, surface2
);
6122 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
6123 IDirectDrawSurface_Release(surface3
);
6125 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
6126 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
6127 refcount
= get_refcount((IUnknown
*)surface2
);
6128 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
6130 /* Automatic detachment on release. */
6131 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6132 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
6133 refcount
= get_refcount((IUnknown
*)surface2
);
6134 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
6135 refcount
= IDirectDrawSurface_Release(surface1
);
6136 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6137 refcount
= IDirectDrawSurface_Release(surface2
);
6138 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6139 refcount
= IDirectDraw2_Release(ddraw
);
6140 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6141 DestroyWindow(window
);
6144 static void test_pixel_format(void)
6146 HWND window
, window2
= NULL
;
6147 HDC hdc
, hdc2
= NULL
;
6149 int format
, test_format
;
6150 PIXELFORMATDESCRIPTOR pfd
;
6151 IDirectDraw2
*ddraw
= NULL
;
6152 IDirectDrawClipper
*clipper
= NULL
;
6154 IDirectDrawSurface
*primary
= NULL
;
6158 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
6159 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
6162 skip("Failed to create window\n");
6166 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
6167 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
6169 hdc
= GetDC(window
);
6172 skip("Failed to get DC\n");
6177 hdc2
= GetDC(window2
);
6179 gl
= LoadLibraryA("opengl32.dll");
6180 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
6182 format
= GetPixelFormat(hdc
);
6183 ok(format
== 0, "new window has pixel format %d\n", format
);
6185 ZeroMemory(&pfd
, sizeof(pfd
));
6186 pfd
.nSize
= sizeof(pfd
);
6188 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
6189 pfd
.iPixelType
= PFD_TYPE_RGBA
;
6190 pfd
.iLayerType
= PFD_MAIN_PLANE
;
6191 format
= ChoosePixelFormat(hdc
, &pfd
);
6194 skip("no pixel format available\n");
6198 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
6200 skip("failed to set pixel format\n");
6204 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
6206 skip("failed to set pixel format on second window\n");
6209 ReleaseDC(window2
, hdc2
);
6214 ddraw
= create_ddraw();
6215 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6217 test_format
= GetPixelFormat(hdc
);
6218 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6220 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6223 skip("Failed to set cooperative level, hr %#x.\n", hr
);
6227 test_format
= GetPixelFormat(hdc
);
6228 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6232 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
6233 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
6234 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
6235 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
6237 test_format
= GetPixelFormat(hdc
);
6238 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6240 test_format
= GetPixelFormat(hdc2
);
6241 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6244 memset(&ddsd
, 0, sizeof(ddsd
));
6245 ddsd
.dwSize
= sizeof(ddsd
);
6246 ddsd
.dwFlags
= DDSD_CAPS
;
6247 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
6249 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
6250 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
6252 test_format
= GetPixelFormat(hdc
);
6253 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6257 test_format
= GetPixelFormat(hdc2
);
6258 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6263 hr
= IDirectDrawSurface2_SetClipper(primary
, clipper
);
6264 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
6266 test_format
= GetPixelFormat(hdc
);
6267 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6269 test_format
= GetPixelFormat(hdc2
);
6270 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6273 memset(&fx
, 0, sizeof(fx
));
6274 fx
.dwSize
= sizeof(fx
);
6275 hr
= IDirectDrawSurface2_Blt(primary
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
6276 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
6278 test_format
= GetPixelFormat(hdc
);
6279 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6283 test_format
= GetPixelFormat(hdc2
);
6284 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6288 if (primary
) IDirectDrawSurface2_Release(primary
);
6289 if (clipper
) IDirectDrawClipper_Release(clipper
);
6290 if (ddraw
) IDirectDraw2_Release(ddraw
);
6291 if (gl
) FreeLibrary(gl
);
6292 if (hdc
) ReleaseDC(window
, hdc
);
6293 if (hdc2
) ReleaseDC(window2
, hdc2
);
6294 DestroyWindow(window
);
6295 if (window2
) DestroyWindow(window2
);
6298 static void test_create_surface_pitch(void)
6300 IDirectDrawSurface
*surface
;
6301 DDSURFACEDESC surface_desc
;
6302 IDirectDraw2
*ddraw
;
6322 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6324 DDSD_PITCH
, 0x100, 0x100},
6325 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6326 DDSD_PITCH
, 0x104, DD_OK
,
6327 DDSD_PITCH
, 0x100, 0x100},
6328 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6329 DDSD_PITCH
, 0x0f8, DD_OK
,
6330 DDSD_PITCH
, 0x100, 0x100},
6331 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6332 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
6334 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6336 DDSD_PITCH
, 0x100, 0x0fc},
6338 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6339 DDSD_PITCH
, 0x104, DD_OK
,
6340 DDSD_PITCH
, 0x100, 0x0fc},
6341 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6342 DDSD_PITCH
, 0x0f8, DD_OK
,
6343 DDSD_PITCH
, 0x100, 0x0fc},
6344 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6345 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
6346 DDSD_PITCH
, 0x100, 0x0fc},
6347 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6348 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
6350 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6351 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
6354 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
6355 0, 0, DDERR_INVALIDCAPS
,
6357 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6359 DDSD_PITCH
, 0x100, 0 },
6360 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6361 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
6363 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
6364 0, 0, DDERR_INVALIDCAPS
,
6366 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6368 DDSD_PITCH
, 0x100, 0 },
6370 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6371 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
6374 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
6376 window
= create_window();
6377 ddraw
= create_ddraw();
6378 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6379 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6380 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6382 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((63 * 4) + 8) * 63);
6384 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6386 memset(&surface_desc
, 0, sizeof(surface_desc
));
6387 surface_desc
.dwSize
= sizeof(surface_desc
);
6388 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
6389 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
6390 surface_desc
.dwWidth
= 63;
6391 surface_desc
.dwHeight
= 63;
6392 U1(surface_desc
).lPitch
= test_data
[i
].pitch_in
;
6393 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6394 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6395 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6396 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6397 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6398 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6399 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6400 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
6402 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
6403 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, expected_hr
);
6404 surface_desc
.lpSurface
= mem
;
6405 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6407 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
6409 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
6413 memset(&surface_desc
, 0, sizeof(surface_desc
));
6414 surface_desc
.dwSize
= sizeof(surface_desc
);
6415 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
6416 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
6417 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
6418 "Test %u: Got unexpected flags %#x, expected %#x.\n",
6419 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
6420 /* The pitch for textures seems to be implementation specific. */
6421 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
6423 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
6424 todo_wine
ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out64
,
6425 "Test %u: Got unexpected pitch %u, expected %u.\n",
6426 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out64
);
6428 ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out32
,
6429 "Test %u: Got unexpected pitch %u, expected %u.\n",
6430 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out32
);
6432 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
6434 IDirectDrawSurface_Release(surface
);
6437 HeapFree(GetProcessHeap(), 0, mem
);
6438 refcount
= IDirectDraw2_Release(ddraw
);
6439 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6440 DestroyWindow(window
);
6443 static void test_mipmap(void)
6445 IDirectDrawSurface
*surface1
;
6446 IDirectDrawSurface2
*surface
, *surface_base
, *surface_mip
;
6447 unsigned int i
, mipmap_count
;
6448 DDSURFACEDESC surface_desc
;
6449 IDirectDraw2
*ddraw
;
6453 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
6462 DWORD mipmap_count_in
;
6464 DWORD mipmap_count_out
;
6468 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
6469 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
, 0},
6470 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
6471 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
, 0},
6472 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 6},
6473 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 6},
6476 window
= create_window();
6477 ddraw
= create_ddraw();
6478 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6479 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6480 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6482 memset(&hal_caps
, 0, sizeof(hal_caps
));
6483 hal_caps
.dwSize
= sizeof(hal_caps
);
6484 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
6485 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
6486 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
6488 skip("Mipmapped textures not supported, skipping tests.\n");
6489 IDirectDraw2_Release(ddraw
);
6490 DestroyWindow(window
);
6494 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
6496 memset(&surface_desc
, 0, sizeof(surface_desc
));
6497 surface_desc
.dwSize
= sizeof(surface_desc
);
6498 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
6499 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
6500 surface_desc
.dwWidth
= tests
[i
].width
;
6501 surface_desc
.dwHeight
= tests
[i
].height
;
6502 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
6503 U2(surface_desc
).dwMipMapCount
= tests
[i
].mipmap_count_in
;
6504 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6505 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
6509 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
6510 ok(SUCCEEDED(hr
), "Test %u: Failed to get IDirectDrawSurface2 interface, hr %#x.\n", i
, hr
);
6511 IDirectDrawSurface_Release(surface1
);
6513 memset(&surface_desc
, 0, sizeof(surface_desc
));
6514 surface_desc
.dwSize
= sizeof(surface_desc
);
6515 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface
, &surface_desc
);
6516 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
6517 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
6518 "Test %u: Got unexpected flags %#x.\n", i
, surface_desc
.dwFlags
);
6519 ok(U2(surface_desc
).dwMipMapCount
== tests
[i
].mipmap_count_out
,
6520 "Test %u: Got unexpected mipmap count %u.\n", i
, U2(surface_desc
).dwMipMapCount
);
6522 surface_base
= surface
;
6523 IDirectDrawSurface2_AddRef(surface_base
);
6524 mipmap_count
= U2(surface_desc
).dwMipMapCount
;
6525 while (mipmap_count
> 1)
6527 hr
= IDirectDrawSurface2_GetAttachedSurface(surface_base
, &caps
, &surface_mip
);
6528 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get attached surface, hr %#x.\n", i
, mipmap_count
, hr
);
6530 memset(&surface_desc
, 0, sizeof(surface_desc
));
6531 surface_desc
.dwSize
= sizeof(surface_desc
);
6532 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface_base
, &surface_desc
);
6533 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get surface desc, hr %#x.\n", i
, mipmap_count
, hr
);
6534 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
6535 "Test %u, %u: Got unexpected flags %#x.\n", i
, mipmap_count
, surface_desc
.dwFlags
);
6536 ok(U2(surface_desc
).dwMipMapCount
== mipmap_count
,
6537 "Test %u, %u: Got unexpected mipmap count %u.\n",
6538 i
, mipmap_count
, U2(surface_desc
).dwMipMapCount
);
6540 memset(&surface_desc
, 0, sizeof(surface_desc
));
6541 surface_desc
.dwSize
= sizeof(surface_desc
);
6542 hr
= IDirectDrawSurface2_Lock(surface_base
, NULL
, &surface_desc
, 0, NULL
);
6543 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#x.\n", i
, mipmap_count
, hr
);
6544 ok(surface_desc
.dwMipMapCount
== mipmap_count
,
6545 "Test %u, %u: unexpected change of mipmap count %u.\n",
6546 i
, mipmap_count
, surface_desc
.dwMipMapCount
);
6547 memset(&surface_desc
, 0, sizeof(surface_desc
));
6548 surface_desc
.dwSize
= sizeof(surface_desc
);
6549 hr
= IDirectDrawSurface2_Lock(surface_mip
, NULL
, &surface_desc
, 0, NULL
);
6550 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#x.\n", i
, mipmap_count
, hr
);
6551 ok(surface_desc
.dwMipMapCount
== mipmap_count
- 1,
6552 "Test %u, %u: Child mipmap count unexpected %u\n", i
, mipmap_count
, surface_desc
.dwMipMapCount
);
6553 IDirectDrawSurface2_Unlock(surface_mip
, NULL
);
6554 IDirectDrawSurface2_Unlock(surface_base
, NULL
);
6556 IDirectDrawSurface2_Release(surface_base
);
6557 surface_base
= surface_mip
;
6560 IDirectDrawSurface2_Release(surface_base
);
6562 IDirectDrawSurface2_Release(surface
);
6565 refcount
= IDirectDraw2_Release(ddraw
);
6566 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6567 DestroyWindow(window
);
6570 static void test_palette_complex(void)
6572 IDirectDrawSurface
*surface1
;
6573 IDirectDrawSurface2
*surface
, *mipmap
, *tmp
;
6574 DDSURFACEDESC surface_desc
;
6575 IDirectDraw2
*ddraw
;
6576 IDirectDrawPalette
*palette
, *palette2
, *palette_mipmap
;
6580 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
6582 PALETTEENTRY palette_entries
[256];
6588 window
= create_window();
6589 ddraw
= create_ddraw();
6590 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6591 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6592 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6594 memset(&hal_caps
, 0, sizeof(hal_caps
));
6595 hal_caps
.dwSize
= sizeof(hal_caps
);
6596 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
6597 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
6598 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
6600 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
6601 IDirectDraw2_Release(ddraw
);
6602 DestroyWindow(window
);
6606 memset(&surface_desc
, 0, sizeof(surface_desc
));
6607 surface_desc
.dwSize
= sizeof(surface_desc
);
6608 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6609 surface_desc
.dwWidth
= 128;
6610 surface_desc
.dwHeight
= 128;
6611 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
6612 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6613 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
6614 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
6615 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6616 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6617 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
6618 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr
);
6619 IDirectDrawSurface_Release(surface1
);
6621 memset(palette_entries
, 0, sizeof(palette_entries
));
6622 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6623 palette_entries
, &palette
, NULL
);
6624 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6626 memset(palette_entries
, 0, sizeof(palette_entries
));
6627 palette_entries
[1].peRed
= 0xff;
6628 palette_entries
[1].peGreen
= 0x80;
6629 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6630 palette_entries
, &palette_mipmap
, NULL
);
6631 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6633 palette2
= (void *)0xdeadbeef;
6634 hr
= IDirectDrawSurface2_GetPalette(surface
, &palette2
);
6635 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
6636 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
6637 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
6638 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6639 hr
= IDirectDrawSurface2_GetPalette(surface
, &palette2
);
6640 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
6641 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
6642 IDirectDrawPalette_Release(palette2
);
6645 IDirectDrawSurface2_AddRef(mipmap
);
6646 for (i
= 0; i
< 7; ++i
)
6648 hr
= IDirectDrawSurface2_GetAttachedSurface(mipmap
, &caps
, &tmp
);
6649 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
6650 palette2
= (void *)0xdeadbeef;
6651 hr
= IDirectDrawSurface2_GetPalette(tmp
, &palette2
);
6652 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
6653 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
6655 hr
= IDirectDrawSurface2_SetPalette(tmp
, palette_mipmap
);
6656 ok(SUCCEEDED(hr
), "Failed to set palette, i %u, hr %#x.\n", i
, hr
);
6658 hr
= IDirectDrawSurface2_GetPalette(tmp
, &palette2
);
6659 ok(SUCCEEDED(hr
), "Failed to get palette, i %u, hr %#x.\n", i
, hr
);
6660 ok(palette_mipmap
== palette2
, "Got unexpected palette %p.\n", palette2
);
6661 IDirectDrawPalette_Release(palette2
);
6663 hr
= IDirectDrawSurface2_GetDC(tmp
, &dc
);
6664 ok(SUCCEEDED(hr
), "Failed to get DC, i %u, hr %#x.\n", i
, hr
);
6665 count
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
6666 ok(count
== 1, "Expected count 1, got %u.\n", count
);
6667 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x.\n", rgbquad
.rgbRed
);
6668 ok(rgbquad
.rgbGreen
== 0x80, "Expected rgbGreen = 0x80, got %#x.\n", rgbquad
.rgbGreen
);
6669 ok(rgbquad
.rgbBlue
== 0x0, "Expected rgbBlue = 0x0, got %#x.\n", rgbquad
.rgbBlue
);
6670 hr
= IDirectDrawSurface2_ReleaseDC(tmp
, dc
);
6671 ok(SUCCEEDED(hr
), "Failed to release DC, i %u, hr %#x.\n", i
, hr
);
6673 IDirectDrawSurface2_Release(mipmap
);
6677 hr
= IDirectDrawSurface2_GetAttachedSurface(mipmap
, &caps
, &tmp
);
6678 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
6679 IDirectDrawSurface2_Release(mipmap
);
6680 refcount
= IDirectDrawSurface2_Release(surface
);
6681 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6682 refcount
= IDirectDrawPalette_Release(palette_mipmap
);
6683 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6684 refcount
= IDirectDrawPalette_Release(palette
);
6685 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6687 refcount
= IDirectDraw2_Release(ddraw
);
6688 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6689 DestroyWindow(window
);
6692 static void test_p8_blit(void)
6694 IDirectDrawSurface
*src
, *dst
, *dst_p8
;
6695 DDSURFACEDESC surface_desc
;
6696 IDirectDraw2
*ddraw
;
6697 IDirectDrawPalette
*palette
, *palette2
;
6701 PALETTEENTRY palette_entries
[256];
6705 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
6706 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
6707 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
6708 static const D3DCOLOR expected
[] =
6710 0x00101010, 0x00010101, 0x00020202, 0x00030303,
6711 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
6715 window
= create_window();
6716 ddraw
= create_ddraw();
6717 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6718 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6719 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6720 is_warp
= ddraw_is_warp(ddraw
);
6722 memset(palette_entries
, 0, sizeof(palette_entries
));
6723 palette_entries
[1].peGreen
= 0xff;
6724 palette_entries
[2].peBlue
= 0xff;
6725 palette_entries
[3].peFlags
= 0xff;
6726 palette_entries
[4].peRed
= 0xff;
6727 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6728 palette_entries
, &palette
, NULL
);
6729 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6730 palette_entries
[1].peBlue
= 0xff;
6731 palette_entries
[2].peGreen
= 0xff;
6732 palette_entries
[3].peRed
= 0xff;
6733 palette_entries
[4].peFlags
= 0x0;
6734 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6735 palette_entries
, &palette2
, NULL
);
6736 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6738 memset(&surface_desc
, 0, sizeof(surface_desc
));
6739 surface_desc
.dwSize
= sizeof(surface_desc
);
6740 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6741 surface_desc
.dwWidth
= 8;
6742 surface_desc
.dwHeight
= 1;
6743 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6744 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6745 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
6746 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
6747 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
6748 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6749 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
6750 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6751 hr
= IDirectDrawSurface_SetPalette(dst_p8
, palette2
);
6752 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6754 memset(&surface_desc
, 0, sizeof(surface_desc
));
6755 surface_desc
.dwSize
= sizeof(surface_desc
);
6756 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6757 surface_desc
.dwWidth
= 8;
6758 surface_desc
.dwHeight
= 1;
6759 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6760 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6761 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
6762 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6763 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6764 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6765 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6766 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
6767 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
6768 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6770 memset(&surface_desc
, 0, sizeof(surface_desc
));
6771 surface_desc
.dwSize
= sizeof(surface_desc
);
6772 hr
= IDirectDrawSurface_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
6773 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
6774 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
6775 hr
= IDirectDrawSurface_Unlock(src
, NULL
);
6776 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
6778 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
6779 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
6780 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
6781 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
6782 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
6784 hr
= IDirectDrawSurface_SetPalette(src
, palette
);
6785 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6786 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
6787 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
6788 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
6789 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
6790 "Failed to blit, hr %#x.\n", hr
);
6794 for (x
= 0; x
< ARRAY_SIZE(expected
); x
++)
6796 color
= get_surface_color(dst
, x
, 0);
6797 todo_wine
ok(compare_color(color
, expected
[x
], 0),
6798 "Pixel %u: Got color %#x, expected %#x.\n",
6799 x
, color
, expected
[x
]);
6803 memset(&fx
, 0, sizeof(fx
));
6804 fx
.dwSize
= sizeof(fx
);
6805 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
6806 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
6807 hr
= IDirectDrawSurface7_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
6808 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
6810 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
6811 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
6812 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
6813 * surface untouched. P8 blits without color keys work. Error checking (DDBLT_KEYSRC without a key
6814 * for example) also works as expected.
6816 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
6817 * the display mode set to P8 doesn't help either. */
6818 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
6819 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
6820 "Got unexpected P8 color key blit result.\n");
6821 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
6822 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
6824 IDirectDrawSurface_Release(src
);
6825 IDirectDrawSurface_Release(dst
);
6826 IDirectDrawSurface_Release(dst_p8
);
6827 IDirectDrawPalette_Release(palette
);
6828 IDirectDrawPalette_Release(palette2
);
6830 refcount
= IDirectDraw2_Release(ddraw
);
6831 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6832 DestroyWindow(window
);
6835 static void test_material(void)
6837 IDirect3DMaterial2
*background
, *material
;
6838 D3DMATERIALHANDLE mat_handle
, tmp
;
6839 IDirect3DViewport2
*viewport
;
6840 IDirect3DDevice2
*device
;
6841 IDirectDrawSurface
*rt
;
6842 IDirectDraw2
*ddraw
;
6850 static D3DVERTEX quad
[] =
6852 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6853 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6854 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6855 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6860 D3DCOLOR expected_color
;
6865 {FALSE
, 0x00ffffff},
6867 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
6869 window
= create_window();
6870 ddraw
= create_ddraw();
6871 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6872 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
6874 skip("Failed to create a 3D device, skipping test.\n");
6875 DestroyWindow(window
);
6879 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
6880 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
6882 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
6883 viewport
= create_viewport(device
, 0, 0, 640, 480);
6884 viewport_set_background(device
, viewport
, background
);
6885 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
6886 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
6888 material
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
6889 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
6890 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
6892 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
6893 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
6894 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
6895 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
6896 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
6897 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
6898 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
6899 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
6900 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, 0);
6901 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
6902 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
6903 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
6904 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
6906 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6908 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
6909 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6911 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, test_data
[i
].material
? mat_handle
: 0);
6912 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
6914 hr
= IDirect3DDevice2_BeginScene(device
);
6915 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6916 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_VERTEX
, quad
, 4, 0);
6917 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
6918 hr
= IDirect3DDevice2_EndScene(device
);
6919 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6920 color
= get_surface_color(rt
, 320, 240);
6921 ok(compare_color(color
, test_data
[i
].expected_color
, 1),
6922 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
6925 destroy_material(material
);
6926 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
6927 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
6928 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
6930 hr
= IDirect3DViewport2_SetBackground(viewport
, mat_handle
);
6931 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
6932 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
6933 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
6934 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
6935 ok(valid
, "Got unexpected valid %#x.\n", valid
);
6936 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6937 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6938 color
= get_surface_color(rt
, 320, 240);
6939 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
6941 hr
= IDirect3DViewport2_SetBackground(viewport
, 0);
6942 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
6943 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
6944 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
6945 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
6946 ok(valid
, "Got unexpected valid %#x.\n", valid
);
6947 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6948 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6949 color
= get_surface_color(rt
, 320, 240);
6950 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
6952 destroy_viewport(device
, viewport
);
6953 viewport
= create_viewport(device
, 0, 0, 640, 480);
6955 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
6956 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
6957 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
6958 ok(!valid
, "Got unexpected valid %#x.\n", valid
);
6959 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6960 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6961 color
= get_surface_color(rt
, 320, 240);
6962 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color
);
6964 destroy_viewport(device
, viewport
);
6965 destroy_material(background
);
6966 destroy_material(material
);
6967 IDirectDrawSurface_Release(rt
);
6968 refcount
= IDirect3DDevice2_Release(device
);
6969 ok(!refcount
, "Device has %u references left.\n", refcount
);
6970 refcount
= IDirectDraw2_Release(ddraw
);
6971 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
6972 DestroyWindow(window
);
6975 static void test_lighting(void)
6977 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
6978 static D3DMATRIX mat
=
6980 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6981 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6982 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6983 0.0f
, 0.0f
, 0.0f
, 1.0f
,
6987 1.0f
, 0.0f
, 1.0f
, 0.0f
,
6988 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6989 1.0f
, 0.0f
, 1.0f
, 0.0f
,
6990 0.0f
, 0.0f
, 0.5f
, 1.0f
,
6994 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6995 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6996 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
6997 10.f
, 10.0f
, 10.0f
, 1.0f
,
7001 1.0f
, 0.0f
, 0.0f
, 0.0f
,
7002 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7003 0.0f
, 0.0f
, 1.0f
, -1.0f
,
7004 10.f
, 10.0f
, 10.0f
, 0.0f
,
7006 static D3DLVERTEX unlitquad
[] =
7008 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
7009 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
7010 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
7011 {{ 0.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
7015 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
7016 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
7017 {{ 0.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
7018 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
7020 static D3DVERTEX unlitnquad
[] =
7022 {{0.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7023 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7024 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7025 {{1.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7029 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7030 {{0.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7031 {{1.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7032 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7036 {{-1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7037 {{-1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7038 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7039 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7043 {{-10.0f
}, {-11.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
7044 {{-10.0f
}, { -9.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
7045 {{-10.0f
}, { -9.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
7046 {{-10.0f
}, {-11.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
7050 {{-11.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7051 {{-11.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7052 {{ -9.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7053 {{ -9.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7055 static WORD indices
[] = {0, 1, 2, 2, 3, 0};
7058 D3DMATRIX
*world_matrix
;
7061 const char *message
;
7065 {&mat
, nquad
, 0x000060ff, "Lit quad with light"},
7066 {&mat_singular
, nquad
, 0x00004db4, "Lit quad with singular world matrix"},
7067 {&mat_transf
, rotatedquad
, 0x000060ff, "Lit quad with transformation matrix"},
7068 {&mat_nonaffine
, translatedquad
, 0x000060ff, "Lit quad with non-affine matrix"},
7071 IDirect3DViewport2
*viewport
, *viewport2
;
7072 D3DMATERIALHANDLE mat_handle
;
7073 IDirect3DMaterial2
*material
;
7074 IDirect3DDevice2
*device
;
7075 IDirectDrawSurface
*rt
;
7076 IDirect3DLight
*light
;
7077 D3DLIGHT2 light_desc
;
7078 IDirectDraw2
*ddraw
;
7086 window
= create_window();
7087 ddraw
= create_ddraw();
7088 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7089 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7091 skip("Failed to create a 3D device, skipping test.\n");
7092 DestroyWindow(window
);
7096 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
7097 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7099 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
7100 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7102 viewport
= create_viewport(device
, 0, 0, 640, 480);
7103 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
7104 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7106 material
= create_diffuse_and_ambient_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
7107 viewport_set_background(device
, viewport
, material
);
7109 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7110 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
7112 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
7113 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
7114 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
7115 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
7116 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
7117 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
7118 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
7119 ok(SUCCEEDED(hr
), "Failed to disable zbuffer, hr %#x.\n", hr
);
7120 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
7121 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
7122 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
7123 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
7125 hr
= IDirect3DDevice2_BeginScene(device
);
7126 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7128 /* There is no D3DRENDERSTATE_LIGHTING on ddraw < 7. */
7129 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
7130 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
7131 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_LVERTEX
, unlitquad
,
7133 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7135 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
7136 ok(SUCCEEDED(hr
), "Failed to enable lighting, hr %#x.\n", hr
);
7137 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_LVERTEX
, litquad
,
7139 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7141 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
7142 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
7143 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, unlitnquad
,
7145 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7147 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
7148 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
7149 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, litnquad
,
7151 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7153 hr
= IDirect3DDevice2_EndScene(device
);
7154 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7156 color
= get_surface_color(rt
, 160, 360);
7157 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color
);
7158 color
= get_surface_color(rt
, 160, 120);
7159 ok(color
== 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color
);
7160 color
= get_surface_color(rt
, 480, 360);
7161 ok(color
== 0x00ffffff, "Unlit quad with normals has color 0x%08x.\n", color
);
7162 color
= get_surface_color(rt
, 480, 120);
7163 ok(color
== 0x00ffffff, "Lit quad with normals has color 0x%08x.\n", color
);
7165 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
7166 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7167 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
7168 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7169 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_AMBIENT
, 0xff002000);
7170 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7172 hr
= IDirect3D2_CreateLight(d3d
, &light
, NULL
);
7173 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7174 memset(&light_desc
, 0, sizeof(light_desc
));
7175 light_desc
.dwSize
= sizeof(light_desc
);
7176 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
7177 U1(light_desc
.dcvColor
).r
= 0.0f
;
7178 U2(light_desc
.dcvColor
).g
= 0.25f
;
7179 U3(light_desc
.dcvColor
).b
= 1.0f
;
7180 U4(light_desc
.dcvColor
).a
= 1.0f
;
7181 U3(light_desc
.dvDirection
).z
= 1.0f
;
7182 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
7183 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7184 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
7185 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7186 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
7187 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
7189 viewport2
= create_viewport(device
, 0, 0, 640, 480);
7190 hr
= IDirect3DViewport2_AddLight(viewport2
, light
);
7191 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
7192 destroy_viewport(device
, viewport2
);
7194 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7195 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7197 hr
= IDirect3DDevice2_BeginScene(device
);
7198 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7200 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, nquad
,
7202 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7204 hr
= IDirect3DDevice2_EndScene(device
);
7205 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7207 color
= get_surface_color(rt
, 320, 240);
7208 ok(color
== 0x00002000, "Lit quad with no light has color 0x%08x.\n", color
);
7210 light_desc
.dwFlags
= D3DLIGHT_ACTIVE
;
7211 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
7212 ok(SUCCEEDED(hr
), "Failed to set light, hr %#x.\n", hr
);
7214 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7216 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, tests
[i
].world_matrix
);
7217 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
7219 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7220 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
7222 hr
= IDirect3DDevice2_BeginScene(device
);
7223 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7225 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
,
7226 tests
[i
].quad
, 4, indices
, 6, 0);
7227 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7229 hr
= IDirect3DDevice2_EndScene(device
);
7230 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7232 color
= get_surface_color(rt
, 320, 240);
7233 ok(color
== tests
[i
].expected
, "%s has color 0x%08x.\n", tests
[i
].message
, color
);
7236 hr
= IDirect3DViewport2_DeleteLight(viewport
, light
);
7237 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#x.\n", hr
);
7238 IDirect3DLight_Release(light
);
7239 destroy_material(material
);
7240 destroy_viewport(device
, viewport
);
7241 IDirectDrawSurface2_Release(rt
);
7242 refcount
= IDirect3DDevice2_Release(device
);
7243 ok(!refcount
, "Device has %u references left.\n", refcount
);
7244 IDirect3D2_Release(d3d
);
7245 refcount
= IDirectDraw2_Release(ddraw
);
7246 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
7247 DestroyWindow(window
);
7250 static void test_specular_lighting(void)
7252 static const unsigned int vertices_side
= 5;
7253 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
7254 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
7255 static D3DMATRIX mat
=
7257 1.0f
, 0.0f
, 0.0f
, 0.0f
,
7258 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7259 0.0f
, 0.0f
, 1.0f
, 0.0f
,
7260 0.0f
, 0.0f
, 0.0f
, 1.0f
,
7262 static D3DLIGHT2 directional
=
7265 D3DLIGHT_DIRECTIONAL
,
7266 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7267 {{0.0f
}, {0.0f
}, {0.0f
}},
7268 {{0.0f
}, {0.0f
}, {1.0f
}},
7274 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7275 {{0.0f
}, {0.0f
}, {0.0f
}},
7276 {{0.0f
}, {0.0f
}, {0.0f
}},
7285 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7286 {{0.0f
}, {0.0f
}, {0.0f
}},
7287 {{0.0f
}, {0.0f
}, {1.0f
}},
7291 M_PI
/ 12.0f
, M_PI
/ 3.0f
7296 D3DLIGHT_PARALLELPOINT
,
7297 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7298 {{0.5f
}, {0.0f
}, {-1.0f
}},
7299 {{0.0f
}, {0.0f
}, {0.0f
}},
7305 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7306 {{-1.1f
}, {0.0f
}, {1.1f
}},
7307 {{0.0f
}, {0.0f
}, {0.0f
}},
7316 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7317 {{0.0f
}, {0.0f
}, {0.1f
}},
7318 {{0.0f
}, {0.0f
}, {0.0f
}},
7323 static const struct expected_color
7328 expected_directional_local
[] =
7330 {160, 120, 0x003c3c3c},
7331 {320, 120, 0x00717171},
7332 {480, 120, 0x003c3c3c},
7333 {160, 240, 0x00717171},
7334 {320, 240, 0x00ffffff},
7335 {480, 240, 0x00717171},
7336 {160, 360, 0x003c3c3c},
7337 {320, 360, 0x00717171},
7338 {480, 360, 0x003c3c3c},
7340 expected_point_local
[] =
7342 {160, 120, 0x00000000},
7343 {320, 120, 0x00090909},
7344 {480, 120, 0x00000000},
7345 {160, 240, 0x00090909},
7346 {320, 240, 0x00fafafa},
7347 {480, 240, 0x00090909},
7348 {160, 360, 0x00000000},
7349 {320, 360, 0x00090909},
7350 {480, 360, 0x00000000},
7352 expected_spot_local
[] =
7354 {160, 120, 0x00000000},
7355 {320, 120, 0x00020202},
7356 {480, 120, 0x00000000},
7357 {160, 240, 0x00020202},
7358 {320, 240, 0x00fafafa},
7359 {480, 240, 0x00020202},
7360 {160, 360, 0x00000000},
7361 {320, 360, 0x00020202},
7362 {480, 360, 0x00000000},
7364 expected_parallelpoint
[] =
7366 {160, 120, 0x00050505},
7367 {320, 120, 0x002c2c2c},
7368 {480, 120, 0x006e6e6e},
7369 {160, 240, 0x00090909},
7370 {320, 240, 0x00717171},
7371 {480, 240, 0x00ffffff},
7372 {160, 360, 0x00050505},
7373 {320, 360, 0x002c2c2c},
7374 {480, 360, 0x006e6e6e},
7376 expected_point_far
[] =
7378 {160, 120, 0x00000000},
7379 {320, 120, 0x00000000},
7380 {480, 120, 0x00000000},
7381 {160, 240, 0x00000000},
7382 {320, 240, 0x00ffffff},
7383 {480, 240, 0x00000000},
7384 {160, 360, 0x00000000},
7385 {320, 360, 0x00000000},
7386 {480, 360, 0x00000000},
7390 {160, 120, 0x00000000},
7391 {320, 120, 0x00000000},
7392 {480, 120, 0x00000000},
7393 {160, 240, 0x00000000},
7394 {320, 240, 0x00000000},
7395 {480, 240, 0x00000000},
7396 {160, 360, 0x00000000},
7397 {320, 360, 0x00000000},
7398 {480, 360, 0x00000000},
7403 float specular_power
;
7404 const struct expected_color
*expected
;
7405 unsigned int expected_count
;
7409 {&directional
, 30.0f
, expected_directional_local
, ARRAY_SIZE(expected_directional_local
)},
7410 {&point
, 30.0f
, expected_point_local
, ARRAY_SIZE(expected_point_local
)},
7411 {&spot
, 30.0f
, expected_spot_local
, ARRAY_SIZE(expected_spot_local
)},
7412 {¶llelpoint
, 30.0f
, expected_parallelpoint
, ARRAY_SIZE(expected_parallelpoint
)},
7413 {&point_side
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7414 {&point_far
, 1.0f
, expected_point_far
, ARRAY_SIZE(expected_point_far
)},
7415 {&directional
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7416 {&point
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7417 {&spot
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7418 {¶llelpoint
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7419 {&point_far
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7422 IDirect3DDevice2
*device
;
7423 IDirectDraw2
*ddraw
;
7424 IDirectDrawSurface
*rt
;
7425 IDirect3DViewport2
*viewport
;
7426 IDirect3DMaterial2
*material
, *background_material
;
7427 IDirect3DLight
*light
;
7428 D3DMATERIALHANDLE mat_handle
;
7433 unsigned int i
, j
, x
, y
;
7437 window
= create_window();
7438 ddraw
= create_ddraw();
7439 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7440 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7442 skip("Failed to create a 3D device, skipping test.\n");
7443 DestroyWindow(window
);
7447 quad
= HeapAlloc(GetProcessHeap(), 0, vertices_side
* vertices_side
* sizeof(*quad
));
7448 indices
= HeapAlloc(GetProcessHeap(), 0, indices_count
* sizeof(*indices
));
7449 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
7451 for (x
= 0; x
< vertices_side
; ++x
)
7453 U1(quad
[i
]).x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
7454 U2(quad
[i
]).y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
7455 U3(quad
[i
]).z
= 1.0f
;
7456 U4(quad
[i
]).nx
= 0.0f
;
7457 U5(quad
[i
]).ny
= 0.0f
;
7458 U6(quad
[i
]).nz
= -1.0f
;
7459 U7(quad
[i
]).tu
= 0.0f
;
7460 U8(quad
[i
++]).tv
= 0.0f
;
7463 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
7465 for (x
= 0; x
< (vertices_side
- 1); ++x
)
7467 indices
[i
++] = y
* vertices_side
+ x
+ 1;
7468 indices
[i
++] = y
* vertices_side
+ x
;
7469 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
7470 indices
[i
++] = y
* vertices_side
+ x
+ 1;
7471 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
7472 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
7476 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
7477 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
7479 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
7480 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
7482 viewport
= create_viewport(device
, 0, 0, 640, 480);
7483 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
7484 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
7486 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
7487 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
7488 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
7489 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
7490 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
7491 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
7492 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
7493 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
7494 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
7495 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
7497 background_material
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
7498 viewport_set_background(device
, viewport
, background_material
);
7500 hr
= IDirect3D2_CreateLight(d3d
, &light
, NULL
);
7501 ok(SUCCEEDED(hr
), "Failed to create a light object, hr %#x.\n", hr
);
7502 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
7503 ok(SUCCEEDED(hr
), "Failed to add a light to the viewport, hr %#x.\n", hr
);
7505 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
7506 ok(SUCCEEDED(hr
), "Failed to enable specular lighting, hr %#x.\n", hr
);
7508 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7510 tests
[i
].light
->dwFlags
= D3DLIGHT_ACTIVE
;
7511 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)tests
[i
].light
);
7512 ok(SUCCEEDED(hr
), "Failed to set light, hr %#x.\n", hr
);
7514 material
= create_specular_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, tests
[i
].specular_power
);
7515 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
7516 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
7517 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
7518 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
7520 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7521 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
7523 hr
= IDirect3DDevice2_BeginScene(device
);
7524 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7526 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
,
7527 quad
, vertices_side
* vertices_side
, indices
, indices_count
, 0);
7528 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7530 hr
= IDirect3DDevice2_EndScene(device
);
7531 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7533 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
7535 color
= get_surface_color(rt
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
7536 ok(compare_color(color
, tests
[i
].expected
[j
].color
, 1),
7537 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
7538 tests
[i
].expected
[j
].color
, tests
[i
].expected
[j
].x
,
7539 tests
[i
].expected
[j
].y
, color
, i
);
7542 destroy_material(material
);
7545 hr
= IDirect3DViewport2_DeleteLight(viewport
, light
);
7546 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#x.\n", hr
);
7547 IDirect3DLight_Release(light
);
7548 destroy_material(background_material
);
7549 destroy_viewport(device
, viewport
);
7550 IDirectDrawSurface2_Release(rt
);
7551 refcount
= IDirect3DDevice2_Release(device
);
7552 ok(!refcount
, "Device has %u references left.\n", refcount
);
7553 IDirect3D2_Release(d3d
);
7554 refcount
= IDirectDraw2_Release(ddraw
);
7555 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
7556 DestroyWindow(window
);
7557 HeapFree(GetProcessHeap(), 0, indices
);
7558 HeapFree(GetProcessHeap(), 0, quad
);
7561 static void test_palette_gdi(void)
7563 IDirectDrawSurface
*surface
, *primary
;
7564 DDSURFACEDESC surface_desc
;
7565 IDirectDraw2
*ddraw
;
7566 IDirectDrawPalette
*palette
, *palette2
;
7570 PALETTEENTRY palette_entries
[256];
7576 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
7577 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
7578 * not the point of this test. */
7579 static const RGBQUAD expected1
[] =
7581 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
7582 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
7584 static const RGBQUAD expected2
[] =
7586 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
7587 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
7589 static const RGBQUAD expected3
[] =
7591 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
7592 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
7594 HPALETTE ddraw_palette_handle
;
7595 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
7596 RGBQUAD rgbquad
[255];
7597 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
7599 window
= create_window();
7600 ddraw
= create_ddraw();
7601 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7602 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7603 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7605 memset(&surface_desc
, 0, sizeof(surface_desc
));
7606 surface_desc
.dwSize
= sizeof(surface_desc
);
7607 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7608 surface_desc
.dwWidth
= 16;
7609 surface_desc
.dwHeight
= 16;
7610 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7611 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7612 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
7613 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
7614 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7615 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7617 /* Avoid colors from the Windows default palette. */
7618 memset(palette_entries
, 0, sizeof(palette_entries
));
7619 palette_entries
[1].peRed
= 0x01;
7620 palette_entries
[2].peGreen
= 0x02;
7621 palette_entries
[3].peBlue
= 0x03;
7622 palette_entries
[4].peRed
= 0x13;
7623 palette_entries
[4].peGreen
= 0x14;
7624 palette_entries
[4].peBlue
= 0x15;
7625 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7626 palette_entries
, &palette
, NULL
);
7627 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7629 /* If there is no palette assigned and the display mode is not 8 bpp, some
7630 * drivers refuse to create a DC while others allow it. If a DC is created,
7631 * the DIB color table is uninitialized and contains random colors. No error
7632 * is generated when trying to read pixels and random garbage is returned.
7634 * The most likely explanation is that if the driver creates a DC, it (or
7635 * the higher-level runtime) uses GetSystemPaletteEntries to find the
7636 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
7637 * contains uninitialized garbage. See comments below for the P8 case. */
7639 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
7640 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7641 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7642 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7643 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
7644 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
7645 "Got unexpected palette %p, expected %p.\n",
7646 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
7648 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7649 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7650 for (i
= 0; i
< ARRAY_SIZE(expected1
); i
++)
7652 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
7653 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7654 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7655 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
7657 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7659 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7660 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7661 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7664 /* Update the palette while the DC is in use. This does not modify the DC. */
7665 palette_entries
[4].peRed
= 0x23;
7666 palette_entries
[4].peGreen
= 0x24;
7667 palette_entries
[4].peBlue
= 0x25;
7668 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
7669 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#x.\n", hr
);
7671 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
7672 ok(i
== 1, "Expected count 1, got %u.\n", i
);
7673 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
7674 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7675 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
7676 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
7678 /* Neither does re-setting the palette. */
7679 hr
= IDirectDrawSurface_SetPalette(surface
, NULL
);
7680 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7681 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
7682 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7684 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
7685 ok(i
== 1, "Expected count 1, got %u.\n", i
);
7686 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
7687 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7688 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
7689 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
7691 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7692 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7694 /* Refresh the DC. This updates the palette. */
7695 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7696 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7697 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7698 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7699 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
7701 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
7702 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7703 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7704 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
7706 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7708 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7709 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7710 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7712 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7713 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7715 refcount
= IDirectDrawSurface_Release(surface
);
7716 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7718 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
7719 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7720 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
7722 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
7723 IDirectDrawPalette_Release(palette
);
7724 IDirectDraw2_Release(ddraw
);
7725 DestroyWindow(window
);
7728 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
7730 memset(&surface_desc
, 0, sizeof(surface_desc
));
7731 surface_desc
.dwSize
= sizeof(surface_desc
);
7732 surface_desc
.dwFlags
= DDSD_CAPS
;
7733 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7734 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
7735 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7737 memset(&fx
, 0, sizeof(fx
));
7738 fx
.dwSize
= sizeof(fx
);
7739 U5(fx
).dwFillColor
= 3;
7740 SetRect(&r
, 0, 0, 319, 479);
7741 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7742 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
7743 SetRect(&r
, 320, 0, 639, 479);
7744 U5(fx
).dwFillColor
= 4;
7745 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7746 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
7748 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
7749 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7750 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
7751 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7753 color
= GetPixel(dc
, 160, 240);
7754 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
7755 color
= GetPixel(dc
, 480, 240);
7756 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
7758 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
7759 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
7760 "Got unexpected palette %p, expected %p.\n",
7761 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
7762 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
7764 /* The primary uses the system palette. In exclusive mode, the system palette matches
7765 * the ddraw palette attached to the primary, so the result is what you would expect
7766 * from a regular surface. Tests for the interaction between the ddraw palette and
7767 * the system palette are not included pending an application that depends on this.
7768 * The relation between those causes problems on Windows Vista and newer for games
7769 * like Age of Empires or StarCraft. Don't emulate it without a real need. */
7770 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7771 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7772 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
7774 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
7775 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7776 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7777 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
7779 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7781 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7782 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7783 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7785 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
7786 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7788 memset(&surface_desc
, 0, sizeof(surface_desc
));
7789 surface_desc
.dwSize
= sizeof(surface_desc
);
7790 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7791 surface_desc
.dwWidth
= 16;
7792 surface_desc
.dwHeight
= 16;
7793 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7794 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7795 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7797 /* Here the offscreen surface appears to use the primary's palette,
7798 * but in all likelihood it is actually the system palette. */
7799 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7800 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7801 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7802 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7803 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
7805 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
7806 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7807 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7808 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
7810 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7812 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7813 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7814 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7816 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7817 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7819 /* On real hardware a change to the primary surface's palette applies immediately,
7820 * even on device contexts from offscreen surfaces that do not have their own
7821 * palette. On the testbot VMs this is not the case. Don't test this until we
7822 * know of an application that depends on this. */
7824 memset(palette_entries
, 0, sizeof(palette_entries
));
7825 palette_entries
[1].peBlue
= 0x40;
7826 palette_entries
[2].peRed
= 0x40;
7827 palette_entries
[3].peGreen
= 0x40;
7828 palette_entries
[4].peRed
= 0x12;
7829 palette_entries
[4].peGreen
= 0x34;
7830 palette_entries
[4].peBlue
= 0x56;
7831 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7832 palette_entries
, &palette2
, NULL
);
7833 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7834 hr
= IDirectDrawSurface_SetPalette(surface
, palette2
);
7835 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7837 /* A palette assigned to the offscreen surface overrides the primary / system
7839 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7840 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7841 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7842 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7843 for (i
= 0; i
< ARRAY_SIZE(expected3
); i
++)
7845 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
7846 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7847 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7848 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
7850 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7852 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7853 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7854 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7856 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7857 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7859 refcount
= IDirectDrawSurface_Release(surface
);
7860 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7862 /* The Windows 8 testbot keeps extra references to the primary and
7863 * backbuffer while in 8 bpp mode. */
7864 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
7865 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
7867 refcount
= IDirectDrawSurface_Release(primary
);
7868 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7869 refcount
= IDirectDrawPalette_Release(palette2
);
7870 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7871 refcount
= IDirectDrawPalette_Release(palette
);
7872 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7873 refcount
= IDirectDraw2_Release(ddraw
);
7874 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7875 DestroyWindow(window
);
7878 static void test_palette_alpha(void)
7880 IDirectDrawSurface
*surface1
;
7881 IDirectDrawSurface2
*surface
;
7882 DDSURFACEDESC surface_desc
;
7883 IDirectDraw2
*ddraw
;
7884 IDirectDrawPalette
*palette
;
7888 PALETTEENTRY palette_entries
[256];
7893 BOOL attach_allowed
;
7898 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
7899 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
7900 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
7903 window
= create_window();
7904 ddraw
= create_ddraw();
7905 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7906 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
7908 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
7909 IDirectDraw2_Release(ddraw
);
7910 DestroyWindow(window
);
7913 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7914 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7916 memset(palette_entries
, 0, sizeof(palette_entries
));
7917 palette_entries
[1].peFlags
= 0x42;
7918 palette_entries
[2].peFlags
= 0xff;
7919 palette_entries
[3].peFlags
= 0x80;
7920 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
7921 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7923 memset(palette_entries
, 0x66, sizeof(palette_entries
));
7924 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
7925 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
7926 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7927 palette_entries
[0].peFlags
);
7928 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7929 palette_entries
[1].peFlags
);
7930 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
7931 palette_entries
[2].peFlags
);
7932 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
7933 palette_entries
[3].peFlags
);
7935 IDirectDrawPalette_Release(palette
);
7937 memset(palette_entries
, 0, sizeof(palette_entries
));
7938 palette_entries
[1].peFlags
= 0x42;
7939 palette_entries
[1].peRed
= 0xff;
7940 palette_entries
[2].peFlags
= 0xff;
7941 palette_entries
[3].peFlags
= 0x80;
7942 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
7943 palette_entries
, &palette
, NULL
);
7944 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7946 memset(palette_entries
, 0x66, sizeof(palette_entries
));
7947 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
7948 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
7949 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7950 palette_entries
[0].peFlags
);
7951 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7952 palette_entries
[1].peFlags
);
7953 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
7954 palette_entries
[2].peFlags
);
7955 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
7956 palette_entries
[3].peFlags
);
7958 for (i
= 0; i
< ARRAY_SIZE(test_data
); i
++)
7960 memset(&surface_desc
, 0, sizeof(surface_desc
));
7961 surface_desc
.dwSize
= sizeof(surface_desc
);
7962 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
7963 surface_desc
.dwWidth
= 128;
7964 surface_desc
.dwHeight
= 128;
7965 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
7966 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7967 ok(SUCCEEDED(hr
), "Failed to create %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
7968 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
7969 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr
);
7970 IDirectDrawSurface_Release(surface1
);
7972 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
7973 if (test_data
[i
].attach_allowed
)
7974 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
7976 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
7984 hr
= IDirectDrawSurface2_GetDC(surface
, &dc
);
7985 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_CANTCREATEDC
) /* Win2k testbot */,
7986 "Failed to get DC, hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
7989 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
7990 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
7991 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
7992 rgbquad
.rgbRed
, test_data
[i
].name
);
7993 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
7994 rgbquad
.rgbGreen
, test_data
[i
].name
);
7995 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
7996 rgbquad
.rgbBlue
, test_data
[i
].name
);
7997 ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
7998 rgbquad
.rgbReserved
, test_data
[i
].name
);
7999 hr
= IDirectDrawSurface2_ReleaseDC(surface
, dc
);
8000 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8003 IDirectDrawSurface2_Release(surface
);
8006 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
8007 memset(&surface_desc
, 0, sizeof(surface_desc
));
8008 surface_desc
.dwSize
= sizeof(surface_desc
);
8009 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8010 surface_desc
.dwWidth
= 128;
8011 surface_desc
.dwHeight
= 128;
8012 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8013 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
8014 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8015 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8016 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8017 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8018 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8019 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8020 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8021 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
8022 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr
);
8023 IDirectDrawSurface_Release(surface1
);
8025 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
8026 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
8027 IDirectDrawSurface2_Release(surface
);
8029 /* The Windows 8 testbot keeps extra references to the primary
8030 * while in 8 bpp mode. */
8031 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
8032 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
8034 refcount
= IDirectDrawPalette_Release(palette
);
8035 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8036 refcount
= IDirectDraw2_Release(ddraw
);
8037 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8038 DestroyWindow(window
);
8041 static void test_lost_device(void)
8043 IDirectDrawSurface
*surface
;
8044 DDSURFACEDESC surface_desc
;
8045 HWND window1
, window2
;
8046 IDirectDraw2
*ddraw
;
8051 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8052 0, 0, 640, 480, 0, 0, 0, 0);
8053 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8054 0, 0, 640, 480, 0, 0, 0, 0);
8055 ddraw
= create_ddraw();
8056 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8057 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8058 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8060 memset(&surface_desc
, 0, sizeof(surface_desc
));
8061 surface_desc
.dwSize
= sizeof(surface_desc
);
8062 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8063 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8064 surface_desc
.dwBackBufferCount
= 1;
8065 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8066 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8068 hr
= IDirectDrawSurface_IsLost(surface
);
8069 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8070 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8071 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8073 ret
= SetForegroundWindow(GetDesktopWindow());
8074 ok(ret
, "Failed to set foreground window.\n");
8075 hr
= IDirectDrawSurface_IsLost(surface
);
8076 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8077 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8078 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8080 ret
= SetForegroundWindow(window1
);
8081 ok(ret
, "Failed to set foreground window.\n");
8082 hr
= IDirectDrawSurface_IsLost(surface
);
8083 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8084 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8085 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8087 hr
= restore_surfaces(ddraw
);
8088 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8089 hr
= IDirectDrawSurface_IsLost(surface
);
8090 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8091 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8092 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8094 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
8095 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8096 hr
= IDirectDrawSurface_IsLost(surface
);
8097 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8098 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8099 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8101 /* Trying to restore the primary will crash, probably because flippable
8102 * surfaces can't exist in DDSCL_NORMAL. */
8103 IDirectDrawSurface_Release(surface
);
8104 memset(&surface_desc
, 0, sizeof(surface_desc
));
8105 surface_desc
.dwSize
= sizeof(surface_desc
);
8106 surface_desc
.dwFlags
= DDSD_CAPS
;
8107 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8108 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8109 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8111 hr
= IDirectDrawSurface_IsLost(surface
);
8112 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8114 ret
= SetForegroundWindow(GetDesktopWindow());
8115 ok(ret
, "Failed to set foreground window.\n");
8116 hr
= IDirectDrawSurface_IsLost(surface
);
8117 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8119 ret
= SetForegroundWindow(window1
);
8120 ok(ret
, "Failed to set foreground window.\n");
8121 hr
= IDirectDrawSurface_IsLost(surface
);
8122 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8124 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8125 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8126 hr
= IDirectDrawSurface_IsLost(surface
);
8127 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8129 hr
= restore_surfaces(ddraw
);
8130 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8131 hr
= IDirectDrawSurface_IsLost(surface
);
8132 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8134 IDirectDrawSurface_Release(surface
);
8135 memset(&surface_desc
, 0, sizeof(surface_desc
));
8136 surface_desc
.dwSize
= sizeof(surface_desc
);
8137 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8138 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8139 surface_desc
.dwBackBufferCount
= 1;
8140 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8141 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8143 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8144 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8145 hr
= IDirectDrawSurface_IsLost(surface
);
8146 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8147 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8148 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8150 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
8151 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8152 hr
= IDirectDrawSurface_IsLost(surface
);
8153 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8154 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8155 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8157 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
8158 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8159 hr
= IDirectDrawSurface_IsLost(surface
);
8160 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8161 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8162 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8164 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
8165 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8166 hr
= IDirectDrawSurface_IsLost(surface
);
8167 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8168 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8169 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8171 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
8172 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8173 hr
= IDirectDrawSurface_IsLost(surface
);
8174 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8175 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8176 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8178 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8179 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8180 hr
= IDirectDrawSurface_IsLost(surface
);
8181 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8182 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8183 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8185 IDirectDrawSurface_Release(surface
);
8186 refcount
= IDirectDraw2_Release(ddraw
);
8187 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8188 DestroyWindow(window2
);
8189 DestroyWindow(window1
);
8192 static void test_surface_desc_lock(void)
8194 IDirectDrawSurface
*surface
;
8195 DDSURFACEDESC surface_desc
;
8196 IDirectDraw2
*ddraw
;
8201 window
= create_window();
8202 ddraw
= create_ddraw();
8203 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8204 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8205 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8207 memset(&surface_desc
, 0, sizeof(surface_desc
));
8208 surface_desc
.dwSize
= sizeof(surface_desc
);
8209 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8210 surface_desc
.dwWidth
= 16;
8211 surface_desc
.dwHeight
= 16;
8212 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8213 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8214 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8216 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
8217 surface_desc
.dwSize
= sizeof(surface_desc
);
8218 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
8219 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
8220 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
8222 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
8223 surface_desc
.dwSize
= sizeof(surface_desc
);
8224 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
8225 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
8226 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
8227 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
8228 surface_desc
.dwSize
= sizeof(surface_desc
);
8229 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
8230 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
8231 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
8232 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8233 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
8235 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
8236 surface_desc
.dwSize
= sizeof(surface_desc
);
8237 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
8238 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
8239 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
8241 IDirectDrawSurface_Release(surface
);
8242 refcount
= IDirectDraw2_Release(ddraw
);
8243 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8244 DestroyWindow(window
);
8247 static void test_texturemapblend(void)
8252 static RECT rect
= {0, 0, 64, 128};
8253 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8255 IDirectDrawSurface
*surface
, *rt
;
8256 IDirect3DTexture2
*texture
;
8257 D3DTEXTUREHANDLE texture_handle
;
8259 IDirectDraw2
*ddraw
;
8260 IDirect3DDevice2
*device
;
8261 IDirect3DMaterial2
*material
;
8262 IDirect3DViewport2
*viewport
;
8266 static D3DTLVERTEX test1_quads
[] =
8268 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {0.0f
}},
8269 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {1.0f
}},
8270 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {0.0f
}},
8271 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {1.0f
}},
8272 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {0.0f
}},
8273 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {1.0f
}},
8274 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {0.0f
}},
8275 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {1.0f
}},
8279 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {0.0f
}},
8280 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {1.0f
}},
8281 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {0.0f
}},
8282 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {1.0f
}},
8283 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {0.0f
}},
8284 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {1.0f
}},
8285 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {0.0f
}},
8286 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {1.0f
}},
8289 window
= create_window();
8290 ddraw
= create_ddraw();
8291 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8292 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8294 skip("Failed to create a 3D device, skipping test.\n");
8295 DestroyWindow(window
);
8296 IDirectDraw2_Release(ddraw
);
8300 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
8301 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
8303 material
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
8304 viewport
= create_viewport(device
, 0, 0, 640, 480);
8305 viewport_set_background(device
, viewport
, material
);
8306 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
8307 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
8309 /* Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel.
8311 * The vertex alpha is completely ignored in this case, so case 1 and 2 combined are not
8312 * a D3DTOP_MODULATE with texture alpha = 0xff in case 2 (no alpha in texture). */
8313 memset(&ddsd
, 0, sizeof(ddsd
));
8314 ddsd
.dwSize
= sizeof(ddsd
);
8315 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8316 ddsd
.dwHeight
= 128;
8318 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8319 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8320 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
8321 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8322 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8323 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8324 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8325 U5(ddsd
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
8326 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8327 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8329 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
8330 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
8331 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
8332 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
8333 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8334 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8336 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8337 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
8339 memset(&fx
, 0, sizeof(fx
));
8340 fx
.dwSize
= sizeof(fx
);
8341 U5(fx
).dwFillColor
= 0xff0000ff;
8342 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8343 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8344 U5(fx
).dwFillColor
= 0x800000ff;
8345 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8346 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8348 /* Note that the ddraw1 version of this test runs tests 1-3 with D3DRENDERSTATE_COLORKEYENABLE
8349 * enabled, whereas this version only runs test 4 with color keying on. Because no color key
8350 * is set on the texture this should not result in different behavior. */
8351 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
8352 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8353 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
8354 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8355 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
8356 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8357 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
8358 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8359 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
8360 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8361 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
8362 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8364 hr
= IDirect3DDevice2_BeginScene(device
);
8365 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8366 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
8367 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8368 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
8369 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8370 hr
= IDirect3DDevice2_EndScene(device
);
8371 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8373 color
= get_surface_color(rt
, 5, 5);
8374 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
8375 color
= get_surface_color(rt
, 400, 5);
8376 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8377 color
= get_surface_color(rt
, 5, 245);
8378 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
8379 color
= get_surface_color(rt
, 400, 245);
8380 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8382 IDirect3DTexture2_Release(texture
);
8383 ref
= IDirectDrawSurface_Release(surface
);
8384 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
8386 /* Test alpha with texture that has no alpha channel - alpha should be taken from diffuse vertex color. */
8387 memset(&ddsd
, 0, sizeof(ddsd
));
8388 ddsd
.dwSize
= sizeof(ddsd
);
8389 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8390 ddsd
.dwHeight
= 128;
8392 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8393 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8394 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8395 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8396 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8397 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8398 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8400 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8401 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8403 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
8404 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
8405 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
8406 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
8407 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8408 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8410 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8411 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
8413 U5(fx
).dwFillColor
= 0xff0000ff;
8414 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8415 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8416 U5(fx
).dwFillColor
= 0x800000ff;
8417 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8418 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8420 hr
= IDirect3DDevice2_BeginScene(device
);
8421 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8422 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
8423 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8424 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
8425 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8426 hr
= IDirect3DDevice2_EndScene(device
);
8427 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8429 color
= get_surface_color(rt
, 5, 5);
8430 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8431 color
= get_surface_color(rt
, 400, 5);
8432 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8433 color
= get_surface_color(rt
, 5, 245);
8434 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
8435 color
= get_surface_color(rt
, 400, 245);
8436 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
8438 IDirect3DTexture2_Release(texture
);
8439 ref
= IDirectDrawSurface_Release(surface
);
8440 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
8442 /* Test RGB - should multiply color components from diffuse vertex color and texture. */
8443 memset(&ddsd
, 0, sizeof(ddsd
));
8444 ddsd
.dwSize
= sizeof(ddsd
);
8445 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8446 ddsd
.dwHeight
= 128;
8448 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8449 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8450 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
8451 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8452 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8453 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8454 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8455 U5(ddsd
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
8456 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8457 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8459 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
8460 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
8461 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
8462 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
8463 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8464 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8466 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8467 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
8469 U5(fx
).dwFillColor
= 0x00ffffff;
8470 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8471 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8472 U5(fx
).dwFillColor
= 0x00ffff80;
8473 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8474 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8476 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
8477 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8479 hr
= IDirect3DDevice2_BeginScene(device
);
8480 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8481 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test2_quads
[0], 4, 0);
8482 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8483 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test2_quads
[4], 4, 0);
8484 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8485 hr
= IDirect3DDevice2_EndScene(device
);
8486 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8488 color
= get_surface_color(rt
, 5, 5);
8489 ok(compare_color(color
, 0x00ff0040, 2), "Got unexpected color 0x%08x.\n", color
);
8490 color
= get_surface_color(rt
, 400, 5);
8491 ok(compare_color(color
, 0x00ff0080, 2), "Got unexpected color 0x%08x.\n", color
);
8492 color
= get_surface_color(rt
, 5, 245);
8493 ok(compare_color(color
, 0x00800080, 2), "Got unexpected color 0x%08x.\n", color
);
8494 color
= get_surface_color(rt
, 400, 245);
8495 ok(compare_color(color
, 0x008000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8497 IDirect3DTexture2_Release(texture
);
8498 ref
= IDirectDrawSurface_Release(surface
);
8499 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
8501 /* Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere). */
8502 memset(&ddsd
, 0, sizeof(ddsd
));
8503 ddsd
.dwSize
= sizeof(ddsd
);
8504 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8505 ddsd
.dwHeight
= 128;
8507 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8508 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8509 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8510 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 16;
8511 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
8512 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
8513 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
8515 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8516 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8518 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
8519 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
8520 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
8521 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
8522 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8523 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8525 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8526 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
8528 U5(fx
).dwFillColor
= 0xf800;
8529 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8530 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8531 U5(fx
).dwFillColor
= 0x001f;
8532 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8533 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
8535 ckey
.dwColorSpaceLowValue
= 0x001f;
8536 ckey
.dwColorSpaceHighValue
= 0x001f;
8537 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
8538 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
8540 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
8541 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8542 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
8543 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
8545 hr
= IDirect3DDevice2_BeginScene(device
);
8546 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8547 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
8548 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8549 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
8550 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8551 hr
= IDirect3DDevice2_EndScene(device
);
8552 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8554 color
= get_surface_color(rt
, 5, 5);
8555 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
8556 color
= get_surface_color(rt
, 400, 5);
8557 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
8558 color
= get_surface_color(rt
, 5, 245);
8559 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
8560 color
= get_surface_color(rt
, 400, 245);
8561 ok(compare_color(color
, 0x00800000, 2), "Got unexpected color 0x%08x.\n", color
);
8563 IDirect3DTexture2_Release(texture
);
8564 ref
= IDirectDrawSurface_Release(surface
);
8565 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
8567 destroy_viewport(device
, viewport
);
8568 ref
= IDirect3DMaterial2_Release(material
);
8569 ok(ref
== 0, "Material not properly released, refcount %u.\n", ref
);
8570 IDirectDrawSurface_Release(rt
);
8571 IDirect3DDevice2_Release(device
);
8572 ref
= IDirectDraw2_Release(ddraw
);
8573 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
8574 DestroyWindow(window
);
8577 static void test_viewport_clear_rect(void)
8580 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8581 static D3DRECT clear_rect2
= {{90}, {90}, {110}, {110}};
8582 IDirectDrawSurface
*rt
;
8584 IDirectDraw2
*ddraw
;
8585 IDirect3DDevice2
*device
;
8586 IDirect3DMaterial2
*red
, *green
;
8587 IDirect3DViewport2
*viewport
, *viewport2
;
8591 window
= create_window();
8592 ddraw
= create_ddraw();
8593 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8594 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8596 skip("Failed to create a 3D device, skipping test.\n");
8597 DestroyWindow(window
);
8598 IDirectDraw2_Release(ddraw
);
8602 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
8603 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
8605 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
8606 viewport
= create_viewport(device
, 0, 0, 640, 480);
8607 viewport_set_background(device
, viewport
, red
);
8608 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8609 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8611 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
8612 viewport2
= create_viewport(device
, 100, 100, 20, 20);
8613 viewport_set_background(device
, viewport2
, green
);
8614 hr
= IDirect3DViewport2_Clear(viewport2
, 1, &clear_rect2
, D3DCLEAR_TARGET
);
8615 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8617 color
= get_surface_color(rt
, 85, 85); /* Outside both. */
8618 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8619 color
= get_surface_color(rt
, 95, 95); /* Outside vp, inside rect. */
8620 /* AMD GPUs ignore the viewport dimensions and only care about the rectangle. */
8621 ok(compare_color(color
, 0x00ff0000, 1) || broken(compare_color(color
, 0x0000ff00, 1)),
8622 "Got unexpected color 0x%08x.\n", color
);
8623 color
= get_surface_color(rt
, 105, 105); /* Inside both. */
8624 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
8625 color
= get_surface_color(rt
, 115, 115); /* Inside vp, outside rect. */
8626 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8627 color
= get_surface_color(rt
, 125, 125); /* Outside both. */
8628 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8630 destroy_viewport(device
, viewport2
);
8631 destroy_material(green
);
8632 destroy_viewport(device
, viewport
);
8633 destroy_material(red
);
8634 IDirectDrawSurface_Release(rt
);
8635 IDirect3DDevice2_Release(device
);
8636 ref
= IDirectDraw2_Release(ddraw
);
8637 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
8638 DestroyWindow(window
);
8641 static void test_color_fill(void)
8644 IDirect3DDevice2
*device
;
8645 IDirectDraw2
*ddraw
;
8646 IDirectDrawSurface
*surface
, *surface2
;
8647 DDSURFACEDESC surface_desc
;
8653 RECT rect
= {5, 5, 7, 7};
8655 DWORD num_fourcc_codes
, *fourcc_codes
;
8657 BOOL support_uyvy
= FALSE
, support_yuy2
= FALSE
;
8661 HRESULT colorfill_hr
, depthfill_hr
;
8666 DDPIXELFORMAT format
;
8671 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
8672 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
8674 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
8675 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
8679 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
8680 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
8682 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
8683 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
8687 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
8688 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
8690 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
8691 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
8695 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
8696 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
8698 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
8699 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
8703 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
,
8704 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0xdeadbeef, TRUE
,
8705 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
8708 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
8709 * different afterwards. DX9+ GPUs set one of the two luminance values
8710 * in each block, but AMD and Nvidia GPUs disagree on which luminance
8711 * value they set. r200 (dx8) just sets the entire block to the clear
8713 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
8714 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
8716 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
8717 {0}, {0}, {0}, {0}, {0}
8721 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
8722 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
8724 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
8725 {0}, {0}, {0}, {0}, {0}
8729 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
8730 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
8732 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
8733 {0}, {0}, {0}, {0}, {0}
8737 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
8738 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
8740 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
8741 {0}, {0}, {0}, {0}, {0}
8745 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
8746 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
8748 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
8749 {0}, {0}, {0}, {0}, {0}
8753 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
8754 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
8756 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
8757 {0}, {0}, {0}, {0}, {0}
8761 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
8762 * surface works, presumably because it is handled by the runtime instead of
8764 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
8765 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
8767 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
8768 {8}, {0}, {0}, {0}, {0}
8772 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
8773 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
8775 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
8776 {8}, {0}, {0}, {0}, {0}
8788 {SRCCOPY
, "SRCCOPY", DD_OK
},
8789 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
8790 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
8791 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
8792 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
8793 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
8794 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
8795 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
8796 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
8797 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
8798 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
8799 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
8800 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
8801 {BLACKNESS
, "BLACKNESS", DD_OK
},
8802 {WHITENESS
, "WHITENESS", DD_OK
},
8803 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
8806 window
= create_window();
8807 ddraw
= create_ddraw();
8808 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8809 is_warp
= ddraw_is_warp(ddraw
);
8810 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8812 skip("Failed to create a 3D device, skipping test.\n");
8813 DestroyWindow(window
);
8814 IDirectDraw2_Release(ddraw
);
8818 hr
= IDirectDraw2_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
8819 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
8820 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
8821 num_fourcc_codes
* sizeof(*fourcc_codes
));
8824 hr
= IDirectDraw2_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
8825 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
8826 for (i
= 0; i
< num_fourcc_codes
; i
++)
8828 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
8829 support_yuy2
= TRUE
;
8830 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
8831 support_uyvy
= TRUE
;
8833 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
8835 memset(&hal_caps
, 0, sizeof(hal_caps
));
8836 hal_caps
.dwSize
= sizeof(hal_caps
);
8837 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
8838 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
8840 if ((!support_yuy2
&& !support_uyvy
) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
8841 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
8843 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
8845 DWORD expected_broken
= tests
[i
].result
;
8846 DWORD mask
= 0xffffffffu
;
8848 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
8849 memset(&fx
, 0, sizeof(fx
));
8850 fx
.dwSize
= sizeof(fx
);
8851 U5(fx
).dwFillColor
= 0xdeadbeef;
8853 memset(&surface_desc
, 0, sizeof(surface_desc
));
8854 surface_desc
.dwSize
= sizeof(surface_desc
);
8855 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8856 surface_desc
.dwWidth
= 64;
8857 surface_desc
.dwHeight
= 64;
8858 surface_desc
.ddpfPixelFormat
= tests
[i
].format
;
8859 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
8861 if (tests
[i
].caps
& DDSCAPS_TEXTURE
)
8863 struct format_support_check check
= {&tests
[i
].format
, FALSE
};
8864 hr
= IDirect3DDevice2_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
8865 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
8866 if (!check
.supported
)
8870 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !support_yuy2
)
8872 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !support_uyvy
)
8874 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
8877 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
8879 surface_desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
8880 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
8881 U2(surface_desc
).dwZBufferBitDepth
= get_device_z_depth(device
);
8882 mask
>>= (32 - U2(surface_desc
).dwZBufferBitDepth
);
8883 /* Some drivers seem to convert depth values incorrectly or not at
8884 * all. Affects at least AMD PALM, 8.17.10.1247. */
8885 if (tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
8890 expected
= tests
[i
].result
& mask
;
8891 f
= ceilf(log2f(expected
+ 1.0f
));
8892 g
= (f
+ 1.0f
) / 2.0f
;
8894 expected_broken
= (expected
/ exp2f(f
) - g
) * 256;
8895 expected_broken
*= 0x01010101;
8899 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8900 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8902 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8903 todo_wine_if (tests
[i
].format
.dwFourCC
)
8904 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
8905 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
8907 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8908 todo_wine_if (tests
[i
].format
.dwFourCC
)
8909 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
8910 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
8912 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
8914 memset(&surface_desc
, 0, sizeof(surface_desc
));
8915 surface_desc
.dwSize
= sizeof(surface_desc
);
8916 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
8917 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8918 color
= surface_desc
.lpSurface
;
8919 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
8920 *color
, tests
[i
].result
, tests
[i
].name
);
8921 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8922 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8925 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8926 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
8927 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
8928 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
8929 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
8930 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
8932 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
8934 memset(&surface_desc
, 0, sizeof(surface_desc
));
8935 surface_desc
.dwSize
= sizeof(surface_desc
);
8936 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
8937 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8938 color
= surface_desc
.lpSurface
;
8939 todo_wine_if(tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
&& U2(surface_desc
).dwZBufferBitDepth
!= 16)
8940 ok((*color
& mask
) == (tests
[i
].result
& mask
) || broken((*color
& mask
) == (expected_broken
& mask
))
8941 || broken(is_warp
&& (*color
& mask
) == (~0u & mask
)) /* Windows 8+ testbot. */,
8942 "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
8943 *color
& mask
, tests
[i
].result
& mask
, tests
[i
].name
);
8944 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8945 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8948 U5(fx
).dwFillColor
= 0xdeadbeef;
8949 fx
.dwROP
= BLACKNESS
;
8950 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
8951 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
8952 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
8953 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
8954 U5(fx
).dwFillColor
, tests
[i
].name
);
8956 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
8958 memset(&surface_desc
, 0, sizeof(surface_desc
));
8959 surface_desc
.dwSize
= sizeof(surface_desc
);
8960 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
8961 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8962 color
= surface_desc
.lpSurface
;
8963 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
8964 *color
, tests
[i
].name
);
8965 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8966 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8969 fx
.dwROP
= WHITENESS
;
8970 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
8971 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
8972 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
8973 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
8974 U5(fx
).dwFillColor
, tests
[i
].name
);
8976 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
8978 memset(&surface_desc
, 0, sizeof(surface_desc
));
8979 surface_desc
.dwSize
= sizeof(surface_desc
);
8980 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
8981 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8982 color
= surface_desc
.lpSurface
;
8983 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
8984 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
8985 *color
, tests
[i
].name
);
8986 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8987 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
8990 IDirectDrawSurface_Release(surface
);
8993 memset(&fx
, 0, sizeof(fx
));
8994 fx
.dwSize
= sizeof(fx
);
8995 U5(fx
).dwFillColor
= 0xdeadbeef;
8996 fx
.dwROP
= WHITENESS
;
8998 memset(&surface_desc
, 0, sizeof(surface_desc
));
8999 surface_desc
.dwSize
= sizeof(surface_desc
);
9000 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9001 surface_desc
.dwWidth
= 64;
9002 surface_desc
.dwHeight
= 64;
9003 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
9004 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9005 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9006 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9007 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9008 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9009 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
9010 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9011 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9012 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
9013 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9016 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
9017 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9018 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
9019 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9021 /* Unused source rectangle. */
9022 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9023 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9024 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9025 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9027 /* Unused source surface. */
9028 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9029 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9030 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9031 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9032 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9033 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9034 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9035 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9037 /* Inverted destination or source rectangle. */
9038 SetRect(&rect
, 5, 7, 7, 5);
9039 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9040 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9041 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9042 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9043 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9044 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9045 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9046 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9047 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9048 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9050 /* Negative rectangle. */
9051 SetRect(&rect
, -1, -1, 5, 5);
9052 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9053 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9054 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9055 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9056 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9057 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9058 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9059 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9060 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9061 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9063 /* Out of bounds rectangle. */
9064 SetRect(&rect
, 0, 0, 65, 65);
9065 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9066 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9067 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9068 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9070 /* Combine multiple flags. */
9071 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9072 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9073 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9074 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9075 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9076 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9078 for (i
= 0; i
< ARRAY_SIZE(rops
); i
++)
9080 fx
.dwROP
= rops
[i
].rop
;
9081 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9082 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#x for rop %s.\n", hr
, rops
[i
].name
);
9085 IDirectDrawSurface_Release(surface2
);
9086 IDirectDrawSurface_Release(surface
);
9088 memset(&surface_desc
, 0, sizeof(surface_desc
));
9089 surface_desc
.dwSize
= sizeof(surface_desc
);
9090 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_ZBUFFERBITDEPTH
;
9091 surface_desc
.dwWidth
= 64;
9092 surface_desc
.dwHeight
= 64;
9093 U2(surface_desc
).dwZBufferBitDepth
= get_device_z_depth(device
);
9094 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
9095 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9096 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9097 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
9098 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9101 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
9102 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9104 /* Unused source rectangle. */
9105 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9106 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9108 /* Unused source surface. */
9109 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9110 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9111 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9112 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9114 /* Inverted destination or source rectangle. */
9115 SetRect(&rect
, 5, 7, 7, 5);
9116 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9117 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9118 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9119 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9120 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9121 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9122 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9123 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9125 /* Negative rectangle. */
9126 SetRect(&rect
, -1, -1, 5, 5);
9127 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9128 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9129 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9130 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9131 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9132 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9133 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9134 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9136 /* Out of bounds rectangle. */
9137 SetRect(&rect
, 0, 0, 65, 65);
9138 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9139 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9141 /* Combine multiple flags. */
9142 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9143 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9145 IDirectDrawSurface_Release(surface2
);
9146 IDirectDrawSurface_Release(surface
);
9149 IDirect3DDevice2_Release(device
);
9150 refcount
= IDirectDraw2_Release(ddraw
);
9151 ok(refcount
== 0, "Ddraw object not properly released, refcount %u.\n", refcount
);
9152 DestroyWindow(window
);
9155 static void test_colorkey_precision(void)
9157 static D3DLVERTEX quad
[] =
9159 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {0.0f
}, {0.0f
}},
9160 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {0.0f
}, {1.0f
}},
9161 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {1.0f
}, {0.0f
}},
9162 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {1.0f
}, {1.0f
}},
9164 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9165 IDirect3DDevice2
*device
;
9166 IDirectDraw2
*ddraw
;
9167 IDirectDrawSurface
*rt
;
9168 IDirect3DViewport2
*viewport
;
9171 IDirectDrawSurface
*src
, *dst
, *texture
;
9172 D3DTEXTUREHANDLE handle
;
9173 IDirect3DTexture2
*d3d_texture
;
9174 IDirect3DMaterial2
*green
;
9175 DDSURFACEDESC surface_desc
, lock_desc
;
9181 DWORD data
[4] = {0}, color_mask
;
9182 BOOL is_nvidia
, is_warp
;
9185 unsigned int max
, shift
, bpp
, clear
;
9193 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
9195 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
9196 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
9201 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
9203 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
9204 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
9209 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
9211 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
9212 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
9217 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
9219 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9220 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
9225 window
= create_window();
9226 ddraw
= create_ddraw();
9227 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9228 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9230 skip("Failed to create a 3D device, skipping test.\n");
9231 DestroyWindow(window
);
9232 IDirectDraw2_Release(ddraw
);
9235 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
9236 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
9238 is_nvidia
= ddraw_is_nvidia(ddraw
);
9239 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
9240 * (color key doesn't match although the values are equal), and a false
9241 * positive when the color key is 0 and the texture contains the value 1.
9242 * I don't want to mark this broken unconditionally since this would
9243 * essentially disable the test on Windows. Also on random occasions
9244 * 254 == 255 and 255 != 255.*/
9245 is_warp
= ddraw_is_warp(ddraw
);
9247 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
9248 viewport
= create_viewport(device
, 0, 0, 640, 480);
9249 viewport_set_background(device
, viewport
, green
);
9250 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
9251 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
9253 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
9254 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
9255 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
9256 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
9257 /* There's no way to ignore the texture color in d3d2, so multiply the texture color
9258 * with a black vertex color. */
9259 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATEALPHA
);
9260 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9262 memset(&fx
, 0, sizeof(fx
));
9263 fx
.dwSize
= sizeof(fx
);
9264 memset(&lock_desc
, 0, sizeof(lock_desc
));
9265 lock_desc
.dwSize
= sizeof(lock_desc
);
9267 for (t
= 0; t
< ARRAY_SIZE(tests
); ++t
)
9269 if (is_nvidia
&& tests
[t
].skip_nv
)
9271 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
9275 memset(&surface_desc
, 0, sizeof(surface_desc
));
9276 surface_desc
.dwSize
= sizeof(surface_desc
);
9277 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9278 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9279 surface_desc
.dwWidth
= 4;
9280 surface_desc
.dwHeight
= 1;
9281 surface_desc
.ddpfPixelFormat
= tests
[t
].fmt
;
9282 /* Windows XP (at least with the r200 driver, other drivers untested) produces
9283 * garbage when doing color keyed texture->texture blits. */
9284 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
9285 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9286 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
9287 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9289 U5(fx
).dwFillColor
= tests
[t
].clear
;
9290 /* On the w8 testbot (WARP driver) the blit result has different values in the
9292 color_mask
= U2(tests
[t
].fmt
).dwRBitMask
9293 | U3(tests
[t
].fmt
).dwGBitMask
9294 | U4(tests
[t
].fmt
).dwBBitMask
;
9296 for (c
= 0; c
<= tests
[t
].max
; ++c
)
9298 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
9299 * texture after it has been set once... */
9300 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
9301 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9302 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
9303 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
9304 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
9305 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9307 hr
= IDirectDrawSurface4_QueryInterface(texture
, &IID_IDirect3DTexture2
, (void **)&d3d_texture
);
9308 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9309 hr
= IDirect3DTexture2_GetHandle(d3d_texture
, device
, &handle
);
9310 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
9311 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, handle
);
9312 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
9313 IDirect3DTexture2_Release(d3d_texture
);
9315 hr
= IDirectDrawSurface_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9316 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
9318 hr
= IDirectDrawSurface_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
9319 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
9320 switch (tests
[t
].bpp
)
9323 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
9324 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
9325 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
9326 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
9330 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
9331 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
9332 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
9333 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
9336 hr
= IDirectDrawSurface_Unlock(src
, 0);
9337 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
9338 hr
= IDirectDrawSurface_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
9339 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
9341 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
9342 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
9343 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
9344 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
9346 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
9347 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
9349 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
9350 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
9351 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
9352 switch (tests
[t
].bpp
)
9355 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
9356 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
9357 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
9358 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
9362 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
9363 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
9364 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
9365 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
9368 hr
= IDirectDrawSurface_Unlock(dst
, 0);
9369 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
9373 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9374 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
9376 if (data
[3] == tests
[t
].clear
)
9378 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
9379 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
9380 * even when a different surface is used. The blit itself doesn't draw anything,
9381 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
9382 * never be masked out by the key.
9384 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
9385 * test is disabled entirely.
9387 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
9388 * terrible on WARP. */
9389 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
9390 IDirectDrawSurface_Release(texture
);
9391 IDirectDrawSurface_Release(src
);
9392 IDirectDrawSurface_Release(dst
);
9397 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9398 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
9400 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9401 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
9403 if (c
== tests
[t
].max
)
9404 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9405 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
9407 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9408 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
9410 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9411 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
9413 hr
= IDirect3DDevice2_BeginScene(device
);
9414 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9415 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
9416 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9417 hr
= IDirect3DDevice2_EndScene(device
);
9418 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9420 color
= get_surface_color(rt
, 80, 240);
9422 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
9423 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9424 color
, tests
[t
].name
, c
);
9426 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
9427 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9428 color
, tests
[t
].name
, c
);
9430 color
= get_surface_color(rt
, 240, 240);
9431 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
9432 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9433 color
, tests
[t
].name
, c
);
9435 color
= get_surface_color(rt
, 400, 240);
9436 if (c
== tests
[t
].max
)
9437 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
9438 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9439 color
, tests
[t
].name
, c
);
9441 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
9442 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9443 color
, tests
[t
].name
, c
);
9445 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
9446 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
9447 IDirectDrawSurface_Release(texture
);
9449 IDirectDrawSurface_Release(src
);
9450 IDirectDrawSurface_Release(dst
);
9454 destroy_viewport(device
, viewport
);
9455 destroy_material(green
);
9456 IDirectDrawSurface_Release(rt
);
9457 IDirect3DDevice2_Release(device
);
9458 refcount
= IDirectDraw2_Release(ddraw
);
9459 ok(refcount
== 0, "Ddraw object not properly released, refcount %u.\n", refcount
);
9460 DestroyWindow(window
);
9463 static void test_range_colorkey(void)
9465 IDirectDraw2
*ddraw
;
9468 IDirectDrawSurface
*surface
;
9469 DDSURFACEDESC surface_desc
;
9473 window
= create_window();
9474 ddraw
= create_ddraw();
9475 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9476 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9477 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9479 memset(&surface_desc
, 0, sizeof(surface_desc
));
9480 surface_desc
.dwSize
= sizeof(surface_desc
);
9481 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
9482 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9483 surface_desc
.dwWidth
= 1;
9484 surface_desc
.dwHeight
= 1;
9485 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9486 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9487 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9488 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9489 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9490 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00000000;
9492 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
9493 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
9494 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
9495 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9496 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9498 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
9499 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
9500 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9501 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9503 /* Same for DDSCAPS_OFFSCREENPLAIN. */
9504 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9505 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
9506 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
9507 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9508 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9510 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
9511 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
9512 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9513 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9515 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
9516 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
9517 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9518 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9520 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
9521 ckey
.dwColorSpaceLowValue
= 0x00000000;
9522 ckey
.dwColorSpaceHighValue
= 0x00000001;
9523 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9524 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
9526 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9527 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
9528 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
9529 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
9531 ckey
.dwColorSpaceLowValue
= 0x00000001;
9532 ckey
.dwColorSpaceHighValue
= 0x00000000;
9533 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9534 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
9536 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9537 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
9538 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
9539 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
9541 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
9542 ckey
.dwColorSpaceLowValue
= 0x00000000;
9543 ckey
.dwColorSpaceHighValue
= 0x00000000;
9544 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9545 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
9547 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
9548 ckey
.dwColorSpaceLowValue
= 0x00000001;
9549 ckey
.dwColorSpaceHighValue
= 0x00000000;
9550 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9551 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9552 ckey
.dwColorSpaceLowValue
= 0x00000000;
9553 ckey
.dwColorSpaceHighValue
= 0x00000001;
9554 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9555 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9556 /* Range destination keys don't work either. */
9557 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
9558 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9560 /* Just to show it's not because of A, R, and G having equal values. */
9561 ckey
.dwColorSpaceLowValue
= 0x00000000;
9562 ckey
.dwColorSpaceHighValue
= 0x01010101;
9563 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9564 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
9566 /* None of these operations modified the key. */
9567 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9568 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
9569 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
9570 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
9572 IDirectDrawSurface_Release(surface
);
9573 refcount
= IDirectDraw2_Release(ddraw
);
9574 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9575 DestroyWindow(window
);
9578 static void test_shademode(void)
9580 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9581 IDirect3DMaterial2
*background
;
9582 IDirect3DViewport2
*viewport
;
9583 IDirect3DDevice2
*device
;
9584 IDirectDrawSurface
*rt
;
9585 DWORD color0
, color1
;
9586 IDirectDraw2
*ddraw
;
9592 static D3DLVERTEX quad_strip
[] =
9594 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
9595 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
9596 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
9597 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
9601 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
9602 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
9603 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
9605 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
9606 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
9607 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
9613 DWORD color0
, color1
;
9617 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
9618 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
9619 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
9620 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
9621 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
9622 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
9625 window
= create_window();
9626 ddraw
= create_ddraw();
9627 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9628 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9630 skip("Failed to create a 3D device, skipping test.\n");
9631 IDirectDraw2_Release(ddraw
);
9632 DestroyWindow(window
);
9636 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
9637 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
9639 background
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
9640 viewport
= create_viewport(device
, 0, 0, 640, 480);
9641 viewport_set_background(device
, viewport
, background
);
9642 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
9643 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
9645 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
9646 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
9648 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
9649 * the color fixups we have to do for FLAT shading will be dependent on that. */
9651 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
9653 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9654 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
9656 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
9657 ok(hr
== D3D_OK
, "Failed to set shade mode, hr %#x.\n", hr
);
9659 hr
= IDirect3DDevice2_BeginScene(device
);
9660 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9661 quad
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? quad_strip
: quad_list
;
9662 count
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? 4 : 6;
9663 hr
= IDirect3DDevice2_DrawPrimitive(device
, tests
[i
].primtype
, D3DVT_LVERTEX
, quad
, count
, 0);
9664 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9665 hr
= IDirect3DDevice2_EndScene(device
);
9666 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9668 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
9669 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
9671 /* For D3DSHADE_FLAT it should take the color of the first vertex of
9672 * each triangle. This requires EXT_provoking_vertex or similar
9673 * functionality being available. */
9674 /* PHONG should be the same as GOURAUD, since no hardware implements
9676 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
9677 i
, color0
, tests
[i
].color0
);
9678 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
9679 i
, color1
, tests
[i
].color1
);
9682 destroy_viewport(device
, viewport
);
9683 destroy_material(background
);
9684 IDirectDrawSurface_Release(rt
);
9685 refcount
= IDirect3DDevice2_Release(device
);
9686 ok(!refcount
, "Device has %u references left.\n", refcount
);
9687 IDirectDraw_Release(ddraw
);
9688 DestroyWindow(window
);
9691 static void test_lockrect_invalid(void)
9694 IDirectDraw2
*ddraw
;
9695 IDirectDrawSurface
*surface1
;
9696 IDirectDrawSurface2
*surface
;
9699 DDSURFACEDESC surface_desc
;
9701 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
9702 static RECT valid
[] =
9710 static RECT invalid
[] =
9712 {68, 60, 60, 68}, /* left > right */
9713 {60, 68, 68, 60}, /* top > bottom */
9714 {-8, 60, 0, 68}, /* left < surface */
9715 {60, -8, 68, 0}, /* top < surface */
9716 {-16, 60, -8, 68}, /* right < surface */
9717 {60, -16, 68, -8}, /* bottom < surface */
9718 {60, 60, 136, 68}, /* right > surface */
9719 {60, 60, 68, 136}, /* bottom > surface */
9720 {136, 60, 144, 68}, /* left > surface */
9721 {60, 136, 68, 144}, /* top > surface */
9731 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, "sysmem offscreenplain", DDERR_INVALIDPARAMS
},
9732 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, "vidmem offscreenplain", DDERR_INVALIDPARAMS
},
9733 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "sysmem texture", DDERR_INVALIDPARAMS
},
9734 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "vidmem texture", DDERR_INVALIDPARAMS
},
9737 window
= create_window();
9738 ddraw
= create_ddraw();
9739 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9740 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9741 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9743 memset(&hal_caps
, 0, sizeof(hal_caps
));
9744 hal_caps
.dwSize
= sizeof(hal_caps
);
9745 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
9746 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
9747 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
9749 skip("Required surface types not supported, skipping test.\n");
9753 for (r
= 0; r
< ARRAY_SIZE(resources
); ++r
)
9755 memset(&surface_desc
, 0, sizeof(surface_desc
));
9756 surface_desc
.dwSize
= sizeof(surface_desc
);
9757 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9758 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
9759 surface_desc
.dwWidth
= 128;
9760 surface_desc
.dwHeight
= 128;
9761 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
9762 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9763 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9764 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xff0000;
9765 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x00ff00;
9766 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x0000ff;
9768 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
9769 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
9770 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
9771 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface2 interface, hr %#x.\n", hr
);
9772 IDirectDrawSurface_Release(surface1
);
9774 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, NULL
, DDLOCK_WAIT
, NULL
);
9775 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, resources
[r
].name
);
9777 for (i
= 0; i
< ARRAY_SIZE(valid
); ++i
)
9779 RECT
*rect
= &valid
[i
];
9781 memset(&surface_desc
, 0, sizeof(surface_desc
));
9782 surface_desc
.dwSize
= sizeof(surface_desc
);
9784 hr
= IDirectDrawSurface2_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9785 ok(SUCCEEDED(hr
), "Lock failed (%#x) for rect %s, type %s.\n",
9786 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
9788 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
9789 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
9792 for (i
= 0; i
< ARRAY_SIZE(invalid
); ++i
)
9794 RECT
*rect
= &invalid
[i
];
9796 memset(&surface_desc
, 1, sizeof(surface_desc
));
9797 surface_desc
.dwSize
= sizeof(surface_desc
);
9799 hr
= IDirectDrawSurface2_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9800 ok(hr
== resources
[r
].hr
, "Lock returned %#x for rect %s, type %s.\n",
9801 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
9804 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
9805 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
9808 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9811 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9812 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#x, type %s.\n",
9813 hr
, resources
[r
].name
);
9814 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9815 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#x, type %s.\n",
9816 hr
, resources
[r
].name
);
9817 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
9818 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
9820 hr
= IDirectDrawSurface2_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
9821 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#x).\n", wine_dbgstr_rect(&valid
[0]), hr
);
9822 hr
= IDirectDrawSurface2_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
9823 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#x).\n",
9824 wine_dbgstr_rect(&valid
[0]), hr
);
9826 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
9827 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
9829 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
9830 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
9832 IDirectDrawSurface2_Release(surface
);
9836 IDirectDraw2_Release(ddraw
);
9837 DestroyWindow(window
);
9840 static void test_yv12_overlay(void)
9842 IDirectDrawSurface
*src_surface
, *dst_surface
;
9843 RECT rect
= {13, 17, 14, 18};
9844 unsigned int offset
, y
;
9845 unsigned char *base
;
9846 IDirectDraw2
*ddraw
;
9851 window
= create_window();
9852 ddraw
= create_ddraw();
9853 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9854 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9855 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9857 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
9859 skip("Failed to create a YV12 overlay, skipping test.\n");
9863 memset(&desc
, 0, sizeof(desc
));
9864 desc
.dwSize
= sizeof(desc
);
9865 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
9866 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
9868 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
9869 "Got unexpected flags %#x.\n", desc
.dwFlags
);
9870 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
9871 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
9872 "Got unexpected caps %#x.\n", desc
.ddsCaps
.dwCaps
);
9873 ok(desc
.dwWidth
== 256, "Got unexpected width %u.\n", desc
.dwWidth
);
9874 ok(desc
.dwHeight
== 256, "Got unexpected height %u.\n", desc
.dwHeight
);
9875 /* The overlay pitch seems to have 256 byte alignment. */
9876 ok(!(U1(desc
).lPitch
& 0xff), "Got unexpected pitch %u.\n", U1(desc
).lPitch
);
9878 /* Fill the surface with some data for the blit test. */
9879 base
= desc
.lpSurface
;
9881 for (y
= 0; y
< desc
.dwHeight
; ++y
)
9883 memset(base
+ U1(desc
).lPitch
* y
, 0x10, desc
.dwWidth
);
9886 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
9888 memset(base
+ U1(desc
).lPitch
* y
, 0x20, desc
.dwWidth
);
9891 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
9893 memset(base
+ U1(desc
).lPitch
* y
, 0x30, desc
.dwWidth
);
9896 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
9897 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
9899 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
9900 * other block-based formats like DXT the entire Y channel is stored in
9901 * one big chunk of memory, followed by the chroma channels. So partial
9902 * locks do not really make sense. Show that they are allowed nevertheless
9903 * and the offset points into the luminance data. */
9904 hr
= IDirectDrawSurface_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
9905 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
9906 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
9907 ok(offset
== rect
.top
* U1(desc
).lPitch
+ rect
.left
, "Got unexpected offset %u, expected %u.\n",
9908 offset
, rect
.top
* U1(desc
).lPitch
+ rect
.left
);
9909 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
9910 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
9912 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
9914 /* Windows XP with a Radeon X1600 GPU refuses to create a second
9915 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
9916 skip("Failed to create a second YV12 surface, skipping blit test.\n");
9917 IDirectDrawSurface_Release(src_surface
);
9921 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
9922 /* VMware rejects YV12 blits. This behavior has not been seen on real
9923 * hardware yet, so mark it broken. */
9924 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#x.\n", hr
);
9928 memset(&desc
, 0, sizeof(desc
));
9929 desc
.dwSize
= sizeof(desc
);
9930 hr
= IDirectDrawSurface_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
9931 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
9933 base
= desc
.lpSurface
;
9934 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
9935 base
+= desc
.dwHeight
* U1(desc
).lPitch
;
9936 todo_wine
ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
9937 base
+= desc
.dwHeight
/ 4 * U1(desc
).lPitch
;
9938 todo_wine
ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
9940 hr
= IDirectDrawSurface_Unlock(dst_surface
, NULL
);
9941 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
9944 IDirectDrawSurface_Release(dst_surface
);
9945 IDirectDrawSurface_Release(src_surface
);
9947 IDirectDraw2_Release(ddraw
);
9948 DestroyWindow(window
);
9951 static BOOL
dwm_enabled(void)
9955 if (!strcmp(winetest_platform
, "wine"))
9957 if (!pDwmIsCompositionEnabled
)
9959 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
9964 static void test_offscreen_overlay(void)
9966 IDirectDrawSurface
*overlay
, *offscreen
, *primary
;
9967 DDSURFACEDESC surface_desc
;
9968 IDirectDraw2
*ddraw
;
9973 window
= create_window();
9974 ddraw
= create_ddraw();
9975 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9976 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9977 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9979 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
9981 skip("Failed to create a UYVY overlay, skipping test.\n");
9985 memset(&surface_desc
, 0, sizeof(surface_desc
));
9986 surface_desc
.dwSize
= sizeof(surface_desc
);
9987 surface_desc
.dwFlags
= DDSD_CAPS
;
9988 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
9989 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
9990 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
9992 /* On Windows 7, and probably Vista, UpdateOverlay() will return
9993 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
9994 * surface prevents this by disabling the dwm. */
9995 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
9996 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9997 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
9998 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
10000 /* Try to overlay a NULL surface. */
10001 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
10002 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10003 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
10004 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10006 /* Try to overlay an offscreen surface. */
10007 memset(&surface_desc
, 0, sizeof(surface_desc
));
10008 surface_desc
.dwSize
= sizeof(surface_desc
);
10009 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
10010 surface_desc
.dwWidth
= 64;
10011 surface_desc
.dwHeight
= 64;
10012 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10013 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10014 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10015 surface_desc
.ddpfPixelFormat
.dwFourCC
= 0;
10016 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
10017 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
10018 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
10019 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
10020 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
10021 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
10023 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
10024 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled())
10025 || broken(hr
== E_NOTIMPL
&& ddraw_is_vmware(ddraw
)),
10026 "Failed to update overlay, hr %#x.\n", hr
);
10028 /* Try to overlay the primary with a non-overlay surface. */
10029 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
10030 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
10031 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
10032 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
10034 IDirectDrawSurface_Release(offscreen
);
10035 IDirectDrawSurface_Release(primary
);
10036 IDirectDrawSurface_Release(overlay
);
10038 IDirectDraw2_Release(ddraw
);
10039 DestroyWindow(window
);
10042 static void test_overlay_rect(void)
10044 IDirectDrawSurface
*overlay
, *primary
= NULL
;
10045 DDSURFACEDESC surface_desc
;
10046 RECT rect
= {0, 0, 64, 64};
10047 IDirectDraw2
*ddraw
;
10053 window
= create_window();
10054 ddraw
= create_ddraw();
10055 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10056 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10057 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10059 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
10061 skip("Failed to create a UYVY overlay, skipping test.\n");
10065 memset(&surface_desc
, 0, sizeof(surface_desc
));
10066 surface_desc
.dwSize
= sizeof(surface_desc
);
10067 surface_desc
.dwFlags
= DDSD_CAPS
;
10068 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
10069 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
10070 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
10072 /* On Windows 7, and probably Vista, UpdateOverlay() will return
10073 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
10074 * surface prevents this by disabling the dwm. */
10075 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
10076 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
10077 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
10078 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
10080 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
10083 win_skip("Cannot disable DWM, skipping overlay test.\n");
10087 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
10088 * used. This is not true in Windows Vista and earlier, but changed in
10090 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
10091 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
10092 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
10093 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
10094 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
10095 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10097 /* Show that the overlay position is the (top, left) coordinate of the
10098 * destination rectangle. */
10099 OffsetRect(&rect
, 32, 16);
10100 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
10101 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
10102 pos_x
= -1; pos_y
= -1;
10103 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
10104 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
10105 ok(pos_x
== rect
.left
, "Got unexpected pos_x %d, expected %d.\n", pos_x
, rect
.left
);
10106 ok(pos_y
== rect
.top
, "Got unexpected pos_y %d, expected %d.\n", pos_y
, rect
.top
);
10108 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
10109 * seen that the overlay overlays the whole primary(==screen). */
10110 hr2
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
10111 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#x.\n", hr2
);
10112 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
10113 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
10114 if (SUCCEEDED(hr2
))
10116 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
10117 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
10121 ok(pos_x
== 32, "Got unexpected pos_x %d.\n", pos_x
);
10122 ok(pos_y
== 16, "Got unexpected pos_y %d.\n", pos_y
);
10125 /* The position cannot be retrieved when the overlay is not shown. */
10126 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
10127 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
10128 pos_x
= -1; pos_y
= -1;
10129 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
10130 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#x.\n", hr
);
10131 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
10132 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
10134 IDirectDrawSurface_Release(overlay
);
10137 IDirectDrawSurface_Release(primary
);
10138 IDirectDraw2_Release(ddraw
);
10139 DestroyWindow(window
);
10142 static void test_blt(void)
10144 IDirectDrawSurface
*surface
, *rt
;
10145 DDSURFACEDESC surface_desc
;
10146 IDirect3DDevice2
*device
;
10147 IDirectDraw2
*ddraw
;
10161 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
10162 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
10163 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
10164 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
10165 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
10166 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
10167 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
10168 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
10169 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
10170 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
10173 window
= create_window();
10174 ddraw
= create_ddraw();
10175 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10176 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10178 skip("Failed to create a 3D device, skipping test.\n");
10179 IDirectDraw2_Release(ddraw
);
10180 DestroyWindow(window
);
10184 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
10185 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10187 memset(&surface_desc
, 0, sizeof(surface_desc
));
10188 surface_desc
.dwSize
= sizeof(surface_desc
);
10189 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
10190 surface_desc
.dwWidth
= 640;
10191 surface_desc
.dwHeight
= 480;
10192 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10193 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10194 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10196 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
10197 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
10199 hr
= IDirectDrawSurface_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
10200 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
10202 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
10204 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
10205 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
10206 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
10208 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
10209 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
10210 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
10212 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
10213 NULL
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
10214 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
10216 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
, NULL
, NULL
, DDBLT_WAIT
, NULL
);
10217 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
10220 IDirectDrawSurface_Release(surface
);
10221 IDirectDrawSurface_Release(rt
);
10222 refcount
= IDirect3DDevice2_Release(device
);
10223 ok(!refcount
, "Device has %u references left.\n", refcount
);
10224 IDirectDraw2_Release(ddraw
);
10225 DestroyWindow(window
);
10228 static void test_blt_z_alpha(void)
10230 DWORD blt_flags
[] =
10234 DDBLT_ALPHADESTCONSTOVERRIDE
,
10235 DDBLT_ALPHADESTNEG
,
10236 DDBLT_ALPHADESTSURFACEOVERRIDE
,
10237 DDBLT_ALPHAEDGEBLEND
,
10240 DDBLT_ALPHASRCCONSTOVERRIDE
,
10242 DDBLT_ALPHASRCSURFACEOVERRIDE
,
10245 DDBLT_ZBUFFERDESTCONSTOVERRIDE
,
10246 DDBLT_ZBUFFERDESTOVERRIDE
,
10247 DDBLT_ZBUFFERSRCCONSTOVERRIDE
,
10248 DDBLT_ZBUFFERSRCOVERRIDE
,
10250 IDirectDrawSurface
*src_surface
, *dst_surface
;
10251 DDSURFACEDESC surface_desc
;
10252 IDirectDraw2
*ddraw
;
10261 window
= create_window();
10262 ddraw
= create_ddraw();
10263 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10264 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10265 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10267 memset(&pf
, 0, sizeof(pf
));
10268 pf
.dwSize
= sizeof(pf
);
10269 pf
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
10270 U1(pf
).dwRGBBitCount
= 32;
10271 U2(pf
).dwRBitMask
= 0x00ff0000;
10272 U3(pf
).dwGBitMask
= 0x0000ff00;
10273 U4(pf
).dwBBitMask
= 0x000000ff;
10274 U5(pf
).dwRGBAlphaBitMask
= 0xff000000;
10276 memset(&surface_desc
, 0, sizeof(surface_desc
));
10277 surface_desc
.dwSize
= sizeof(surface_desc
);
10278 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
10279 surface_desc
.dwWidth
= 64;
10280 surface_desc
.dwHeight
= 64;
10281 surface_desc
.ddpfPixelFormat
= pf
;
10282 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10284 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
10285 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
10286 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
10287 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
10289 memset(&fx
, 0, sizeof(fx
));
10290 fx
.dwSize
= sizeof(fx
);
10291 fx
.dwZBufferOpCode
= D3DCMP_NEVER
;
10292 fx
.dwZDestConstBitDepth
= 32;
10293 U1(fx
).dwZDestConst
= 0x11111111;
10294 fx
.dwZSrcConstBitDepth
= 32;
10295 U2(fx
).dwZSrcConst
= 0xeeeeeeee;
10296 fx
.dwAlphaEdgeBlendBitDepth
= 8;
10297 fx
.dwAlphaEdgeBlend
= 0x7f;
10298 fx
.dwAlphaDestConstBitDepth
= 8;
10299 U3(fx
).dwAlphaDestConst
= 0xdd;
10300 fx
.dwAlphaSrcConstBitDepth
= 8;
10301 U4(fx
).dwAlphaSrcConst
= 0x22;
10303 for (i
= 0; i
< ARRAY_SIZE(blt_flags
); ++i
)
10305 U5(fx
).dwFillColor
= 0x3300ff00;
10306 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10307 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
10309 U5(fx
).dwFillColor
= 0xccff0000;
10310 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10311 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
10313 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, blt_flags
[i
] | DDBLT_WAIT
, &fx
);
10314 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
10316 color
= get_surface_color(dst_surface
, 32, 32);
10317 ok(compare_color(color
, 0x0000ff00, 0), "Test %u: Got unexpected color 0x%08x.\n", i
, color
);
10320 IDirectDrawSurface_Release(dst_surface
);
10321 IDirectDrawSurface_Release(src_surface
);
10322 refcount
= IDirectDraw2_Release(ddraw
);
10323 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
10324 DestroyWindow(window
);
10327 static void test_cross_device_blt(void)
10329 IDirectDrawSurface
*surface
, *surface2
, *sysmem_surface
;
10330 IDirect3DDevice2
*device
, *device2
;
10331 IDirectDraw2
*ddraw
, *ddraw2
;
10332 DDSURFACEDESC surface_desc
;
10333 HWND window
, window2
;
10339 window
= create_window();
10340 ddraw
= create_ddraw();
10341 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
10343 skip("Failed to create a 3D device.\n");
10344 IDirectDraw2_Release(ddraw
);
10345 DestroyWindow(window
);
10349 window2
= create_window();
10350 ddraw2
= create_ddraw();
10351 if (!(device2
= create_device(ddraw2
, window2
, DDSCL_NORMAL
)))
10353 skip("Failed to create a 3D device.\n");
10354 IDirectDraw2_Release(ddraw2
);
10355 IDirect3DDevice2_Release(device
);
10356 IDirectDraw2_Release(ddraw
);
10357 DestroyWindow(window
);
10358 DestroyWindow(window2
);
10362 memset(&surface_desc
, 0, sizeof(surface_desc
));
10363 surface_desc
.dwSize
= sizeof(surface_desc
);
10364 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
10365 surface_desc
.dwWidth
= 640;
10366 surface_desc
.dwHeight
= 480;
10367 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10368 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
10369 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10371 memset(&surface_desc
, 0, sizeof(surface_desc
));
10372 surface_desc
.dwSize
= sizeof(surface_desc
);
10373 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
10374 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_VIDEOMEMORY
;
10375 surface_desc
.dwBackBufferCount
= 2;
10376 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10377 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10379 memset(&surface_desc
, 0, sizeof(surface_desc
));
10380 surface_desc
.dwSize
= sizeof(surface_desc
);
10381 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
10382 surface_desc
.dwWidth
= 640;
10383 surface_desc
.dwHeight
= 480;
10384 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10385 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10386 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10387 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
10388 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00007c00;
10389 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x000003e0;
10390 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x0000001f;
10391 hr
= IDirectDraw2_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
10392 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10394 memset(&fx
, 0, sizeof(fx
));
10395 fx
.dwSize
= sizeof(fx
);
10396 U5(fx
).dwFillColor
= 0xff0000ff;
10397 hr
= IDirectDrawSurface_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10398 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
10400 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10401 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
10402 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
10403 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10404 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10405 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
10406 color
= get_surface_color(surface
, 320, 240);
10407 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
10409 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10410 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
10411 color
= get_surface_color(sysmem_surface
, 320, 240);
10412 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
10414 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10415 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10416 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
10417 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10419 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10420 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
10421 color
= get_surface_color(sysmem_surface
, 320, 240);
10422 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
10424 IDirectDrawSurface_Release(surface2
);
10425 memset(&surface_desc
, 0, sizeof(surface_desc
));
10426 surface_desc
.dwSize
= sizeof(surface_desc
);
10427 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
10428 surface_desc
.dwWidth
= 640;
10429 surface_desc
.dwHeight
= 480;
10430 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10431 hr
= IDirectDraw2_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
10432 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10433 hr
= IDirectDrawSurface_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10434 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
10436 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10437 todo_wine
ok(hr
== D3D_OK
, "Failed to blit, hr %#x.\n", hr
);
10438 color
= get_surface_color(sysmem_surface
, 320, 240);
10439 todo_wine
ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
10441 IDirectDrawSurface_Release(surface
);
10442 IDirectDrawSurface_Release(surface2
);
10443 IDirectDrawSurface_Release(sysmem_surface
);
10444 refcount
= IDirect3DDevice2_Release(device
);
10445 ok(!refcount
, "Device has %u references left.\n", refcount
);
10446 refcount
= IDirect3DDevice2_Release(device2
);
10447 ok(!refcount
, "Device has %u references left.\n", refcount
);
10448 IDirectDraw2_Release(ddraw
);
10449 IDirectDraw2_Release(ddraw2
);
10450 DestroyWindow(window
);
10451 DestroyWindow(window2
);
10454 static void test_getdc(void)
10456 IDirectDrawSurface
*surface
, *surface2
, *tmp
;
10457 DDSURFACEDESC surface_desc
, map_desc
;
10458 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
10459 IDirectDraw2
*ddraw
;
10465 static const struct
10468 DDPIXELFORMAT format
;
10469 BOOL getdc_supported
;
10470 HRESULT alt_result
;
10474 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
10475 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
10476 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
10477 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
10478 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
10479 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
10480 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
10481 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
10482 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
10483 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
10484 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
10485 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
10486 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
10487 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
10488 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
10489 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
10490 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
10491 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
10492 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
10493 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
10494 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
10495 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
10496 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
10497 * This is not implemented in wine yet, so disable the test for now.
10498 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
10499 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
10500 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
10502 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
10503 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10504 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
10505 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
10506 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
10507 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10508 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
10509 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10510 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
10511 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10512 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
10513 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10514 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
10515 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10518 window
= create_window();
10519 ddraw
= create_ddraw();
10520 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10521 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10522 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10524 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
10526 memset(&surface_desc
, 0, sizeof(surface_desc
));
10527 surface_desc
.dwSize
= sizeof(surface_desc
);
10528 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10529 surface_desc
.dwWidth
= 64;
10530 surface_desc
.dwHeight
= 64;
10531 surface_desc
.ddpfPixelFormat
= test_data
[i
].format
;
10532 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10534 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
10536 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10537 if (FAILED(hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
10539 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", test_data
[i
].name
, hr
);
10544 dc
= (void *)0x1234;
10545 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10546 if (test_data
[i
].getdc_supported
)
10547 ok(SUCCEEDED(hr
) || broken(hr
== test_data
[i
].alt_result
|| ddraw_is_vmware(ddraw
)),
10548 "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10550 ok(FAILED(hr
), "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10554 unsigned int width_bytes
;
10560 type
= GetObjectType(dc
);
10561 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
10562 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
10563 type
= GetObjectType(bitmap
);
10564 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
10566 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
10567 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
10568 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
10569 dib
.dsBm
.bmType
, test_data
[i
].name
);
10570 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
10571 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
10572 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
10573 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
10574 width_bytes
= ((dib
.dsBm
.bmWidth
* U1(test_data
[i
].format
).dwRGBBitCount
+ 31) >> 3) & ~3;
10575 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
10576 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
10577 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
10578 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
10579 ok(dib
.dsBm
.bmBitsPixel
== U1(test_data
[i
].format
).dwRGBBitCount
,
10580 "Got unexpected bit count %d for format %s.\n",
10581 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
10582 ok(!!dib
.dsBm
.bmBits
, "Got unexpected bits %p for format %s.\n",
10583 dib
.dsBm
.bmBits
, test_data
[i
].name
);
10585 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %u for format %s.\n",
10586 dib
.dsBmih
.biSize
, test_data
[i
].name
);
10587 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
10588 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
10589 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
10590 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
10591 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
10592 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
10593 ok(dib
.dsBmih
.biBitCount
== U1(test_data
[i
].format
).dwRGBBitCount
,
10594 "Got unexpected bit count %u for format %s.\n",
10595 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
10596 ok(dib
.dsBmih
.biCompression
== (U1(test_data
[i
].format
).dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
10597 || broken(U1(test_data
[i
].format
).dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
10598 "Got unexpected compression %#x for format %s.\n",
10599 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
10600 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %u for format %s.\n",
10601 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
10602 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %d for format %s.\n",
10603 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
10604 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %d for format %s.\n",
10605 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
10606 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %u for format %s.\n",
10607 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
10608 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %u for format %s.\n",
10609 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
10611 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
10613 ok((dib
.dsBitfields
[0] == U2(test_data
[i
].format
).dwRBitMask
10614 && dib
.dsBitfields
[1] == U3(test_data
[i
].format
).dwGBitMask
10615 && dib
.dsBitfields
[2] == U4(test_data
[i
].format
).dwBBitMask
)
10616 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
10617 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
10618 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
10622 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
10623 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
10624 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
10626 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
10627 ok(!dib
.dsOffset
, "Got unexpected offset %u for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
10629 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10630 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10634 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
10637 IDirectDrawSurface_Release(surface
);
10642 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
10643 if (FAILED(hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
10645 skip("Failed to create mip-mapped texture for format %s (hr %#x), skipping tests.\n",
10646 test_data
[i
].name
, hr
);
10650 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
10651 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10652 hr
= IDirectDrawSurface_GetAttachedSurface(tmp
, &caps
, &surface2
);
10653 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10654 IDirectDrawSurface_Release(tmp
);
10656 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10657 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10658 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10659 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10660 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
10661 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10662 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
10663 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10665 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10666 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10667 dc2
= (void *)0x1234;
10668 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
10669 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10670 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
10671 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10672 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10673 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10674 ok(hr
== DDERR_NODC
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10676 map_desc
.dwSize
= sizeof(map_desc
);
10677 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10678 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10679 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10680 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10681 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10682 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10683 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10684 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10686 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10687 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10688 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10689 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10690 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10691 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10693 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10694 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10695 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10696 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10697 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10698 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10699 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10700 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10702 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10703 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10704 hr
= IDirectDrawSurface_GetDC(surface2
, &dc2
);
10705 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10706 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc2
);
10707 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10708 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10709 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10711 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
10712 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10713 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
10714 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10715 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc2
);
10716 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10717 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
10718 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10720 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10721 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10722 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10723 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10724 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
10725 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10726 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10727 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10729 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10730 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10731 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10732 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10733 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10734 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10735 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10736 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10738 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10739 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10740 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10741 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10742 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10743 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10744 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
10745 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10747 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10748 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10749 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10750 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10751 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
10752 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10753 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10754 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10756 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
10757 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10758 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10759 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10760 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10761 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10762 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
10763 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10765 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10766 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10767 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
10768 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10769 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10770 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10771 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
10772 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10773 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10774 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10776 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
10777 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10778 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10779 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10780 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
10781 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10782 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10783 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
10784 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
10785 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
10787 IDirectDrawSurface_Release(surface2
);
10788 IDirectDrawSurface_Release(surface
);
10791 IDirectDraw2_Release(ddraw
);
10792 DestroyWindow(window
);
10795 static void test_draw_primitive(void)
10797 static WORD indices
[] = {0, 1, 2, 3};
10798 static D3DVERTEX quad
[] =
10800 {{-1.0f
}, {-1.0f
}, {0.0f
}},
10801 {{-1.0f
}, { 1.0f
}, {0.0f
}},
10802 {{ 1.0f
}, {-1.0f
}, {0.0f
}},
10803 {{ 1.0f
}, { 1.0f
}, {0.0f
}},
10805 IDirect3DViewport2
*viewport
;
10806 IDirect3DDevice2
*device
;
10807 IDirectDraw2
*ddraw
;
10813 window
= create_window();
10814 ddraw
= create_ddraw();
10815 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10816 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10818 skip("Failed to create a 3D device, skipping test.\n");
10819 IDirectDraw2_Release(ddraw
);
10820 DestroyWindow(window
);
10824 viewport
= create_viewport(device
, 0, 0, 640, 480);
10825 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
10826 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
10828 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
10829 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
10831 IDirect3D2_Release(d3d
);
10833 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, NULL
, 0, 0);
10834 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10835 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, 0);
10836 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10838 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, indices
, 4, 0);
10839 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10841 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, NULL
, 0, 0);
10842 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10843 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
10844 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10845 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, indices
, 4, 0);
10846 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10848 destroy_viewport(device
, viewport
);
10849 refcount
= IDirect3DDevice2_Release(device
);
10850 ok(!refcount
, "Device has %u references left.\n", refcount
);
10851 IDirectDraw2_Release(ddraw
);
10852 DestroyWindow(window
);
10855 static void test_edge_antialiasing_blending(void)
10857 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10858 IDirect3DMaterial2
*green_background
;
10859 IDirect3DMaterial2
*red_background
;
10860 IDirectDrawSurface
*offscreen
, *ds
;
10861 D3DDEVICEDESC hal_desc
, hel_desc
;
10862 IDirect3DViewport2
*viewport
;
10863 DDSURFACEDESC surface_desc
;
10864 IDirect3DDevice2
*device
;
10865 IDirectDraw2
*ddraw
;
10871 static D3DMATRIX mat
=
10873 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10874 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10875 0.0f
, 0.0f
, 1.0f
, 0.0f
,
10876 0.0f
, 0.0f
, 0.0f
, 1.0f
,
10878 static D3DLVERTEX green_quad
[] =
10880 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
10881 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
10882 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
10883 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
10885 static D3DLVERTEX red_quad
[] =
10887 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xccff0000}},
10888 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xccff0000}},
10889 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xccff0000}},
10890 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xccff0000}},
10893 window
= create_window();
10894 ddraw
= create_ddraw();
10895 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10896 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10898 skip("Failed to create a 3D device.\n");
10899 DestroyWindow(window
);
10903 memset(&hal_desc
, 0, sizeof(hal_desc
));
10904 hal_desc
.dwSize
= sizeof(hal_desc
);
10905 memset(&hel_desc
, 0, sizeof(hel_desc
));
10906 hel_desc
.dwSize
= sizeof(hel_desc
);
10907 hr
= IDirect3DDevice2_GetCaps(device
, &hal_desc
, &hel_desc
);
10908 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
10909 trace("HAL line edge antialiasing support: %#x.\n",
10910 hal_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
10911 trace("HAL triangle edge antialiasing support: %#x.\n",
10912 hal_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
10913 trace("HEL line edge antialiasing support: %#x.\n",
10914 hel_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
10915 trace("HEL triangle edge antialiasing support: %#x.\n",
10916 hel_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
10918 memset(&surface_desc
, 0, sizeof(surface_desc
));
10919 surface_desc
.dwSize
= sizeof(surface_desc
);
10920 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
10921 surface_desc
.dwWidth
= 640;
10922 surface_desc
.dwHeight
= 480;
10923 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
10924 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10925 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
10926 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
10927 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10928 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10929 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10930 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
10931 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
10932 ok(hr
== D3D_OK
, "Creating the offscreen render target failed, hr %#x.\n", hr
);
10934 ds
= get_depth_stencil(device
);
10935 hr
= IDirectDrawSurface_AddAttachedSurface(offscreen
, ds
);
10936 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
10937 IDirectDrawSurface_Release(ds
);
10939 hr
= IDirect3DDevice2_SetRenderTarget(device
, offscreen
, 0);
10940 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
10942 red_background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 0.8f
);
10943 green_background
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.5f
);
10945 viewport
= create_viewport(device
, 0, 0, 640, 480);
10946 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
10947 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
10949 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
10950 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
10951 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
10952 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
10953 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
10954 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
10955 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
10956 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
10957 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
10958 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
10959 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
10960 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
10962 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
10963 ok(SUCCEEDED(hr
), "Failed to enable blending, hr %#x.\n", hr
);
10964 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
10965 ok(SUCCEEDED(hr
), "Failed to set src blend, hr %#x.\n", hr
);
10966 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
10967 ok(SUCCEEDED(hr
), "Failed to set dest blend, hr %#x.\n", hr
);
10969 viewport_set_background(device
, viewport
, red_background
);
10970 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10971 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
10972 hr
= IDirect3DDevice2_BeginScene(device
);
10973 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10974 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
10975 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10976 hr
= IDirect3DDevice2_EndScene(device
);
10977 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10978 color
= get_surface_color(offscreen
, 320, 240);
10979 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
10981 viewport_set_background(device
, viewport
, green_background
);
10982 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10983 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
10984 hr
= IDirect3DDevice2_BeginScene(device
);
10985 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10986 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
10987 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10988 hr
= IDirect3DDevice2_EndScene(device
);
10989 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10990 color
= get_surface_color(offscreen
, 320, 240);
10991 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
10993 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
10994 ok(SUCCEEDED(hr
), "Failed to disable blending, hr %#x.\n", hr
);
10996 viewport_set_background(device
, viewport
, red_background
);
10997 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10998 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
10999 hr
= IDirect3DDevice2_BeginScene(device
);
11000 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11001 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
11002 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11003 hr
= IDirect3DDevice2_EndScene(device
);
11004 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11005 color
= get_surface_color(offscreen
, 320, 240);
11006 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
11008 viewport_set_background(device
, viewport
, green_background
);
11009 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11010 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
11011 hr
= IDirect3DDevice2_BeginScene(device
);
11012 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11013 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
11014 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11015 hr
= IDirect3DDevice2_EndScene(device
);
11016 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11017 color
= get_surface_color(offscreen
, 320, 240);
11018 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
11020 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_EDGEANTIALIAS
, TRUE
);
11021 ok(SUCCEEDED(hr
), "Failed to enable edge antialiasing, hr %#x.\n", hr
);
11023 viewport_set_background(device
, viewport
, red_background
);
11024 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11025 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
11026 hr
= IDirect3DDevice2_BeginScene(device
);
11027 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11028 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
11029 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11030 hr
= IDirect3DDevice2_EndScene(device
);
11031 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11032 color
= get_surface_color(offscreen
, 320, 240);
11033 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
11035 viewport_set_background(device
, viewport
, green_background
);
11036 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11037 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
11038 hr
= IDirect3DDevice2_BeginScene(device
);
11039 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11040 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
11041 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11042 hr
= IDirect3DDevice2_EndScene(device
);
11043 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11044 color
= get_surface_color(offscreen
, 320, 240);
11045 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
11047 IDirectDrawSurface_Release(offscreen
);
11048 destroy_viewport(device
, viewport
);
11049 destroy_material(red_background
);
11050 destroy_material(green_background
);
11051 refcount
= IDirect3DDevice2_Release(device
);
11052 ok(!refcount
, "Device has %u references left.\n", refcount
);
11053 IDirectDraw2_Release(ddraw
);
11054 DestroyWindow(window
);
11057 /* TransformVertices always writes 32 bytes regardless of the input / output stride.
11058 * The stride is honored for navigating to the next vertex. 3 floats input position
11059 * are read, and 16 bytes extra vertex data are copied around. */
11060 struct transform_input
11062 float x
, y
, z
, unused1
; /* Position data, transformed. */
11063 DWORD v1
, v2
, v3
, v4
; /* Extra data, e.g. color and texture coords, copied. */
11067 struct transform_output
11070 DWORD v1
, v2
, v3
, v4
;
11071 DWORD unused3
, unused4
;
11074 static void test_transform_vertices(void)
11076 IDirect3DDevice2
*device
;
11077 IDirectDrawSurface
*rt
;
11078 IDirectDraw2
*ddraw
;
11083 IDirect3DViewport2
*viewport
;
11084 IDirect3DMaterial2
*background
;
11086 static struct transform_input position_tests
[] =
11088 { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
11089 { 1.0f
, 1.0f
, 1.0f
, 8.0f
, 6, 7, 8, 9, 10},
11090 {-1.0f
, -1.0f
, -1.0f
, 4.0f
, 11, 12, 13, 14, 15},
11091 { 0.5f
, 0.5f
, 0.5f
, 2.0f
, 16, 17, 18, 19, 20},
11092 {-0.5f
, -0.5f
, -0.5f
, 1.0f
, ~1U, ~2U, ~3U, ~4U, ~5U},
11093 {-0.5f
, -0.5f
, 0.0f
, 0.0f
, ~6U, ~7U, ~8U, ~9U, ~0U},
11095 static struct transform_input cliptest
[] =
11097 { 25.59f
, 25.59f
, 1.0f
, 0.0f
, 1, 2, 3, 4, 5},
11098 { 25.61f
, 25.61f
, 1.01f
, 0.0f
, 1, 2, 3, 4, 5},
11099 {-25.59f
, -25.59f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
11100 {-25.61f
, -25.61f
, -0.01f
, 0.0f
, 1, 2, 3, 4, 5},
11102 static struct transform_input offscreentest
[] =
11104 {128.1f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
11106 struct transform_output out
[ARRAY_SIZE(position_tests
)];
11107 D3DHVERTEX out_h
[ARRAY_SIZE(position_tests
)];
11108 D3DTRANSFORMDATA transformdata
;
11109 static const D3DVIEWPORT vp_template
=
11111 sizeof(vp_template
), 0, 0, 256, 256, 5.0f
, 5.0f
, 256.0f
, 256.0f
, -25.0f
, 60.0f
11113 D3DVIEWPORT vp_data
=
11115 sizeof(vp_data
), 0, 0, 256, 256, 1.0f
, 1.0f
, 256.0f
, 256.0f
, 0.0f
, 1.0f
11117 D3DVIEWPORT2 vp2_data
;
11120 static D3DMATRIX mat_scale
=
11122 2.0f
, 0.0f
, 0.0f
, 0.0f
,
11123 0.0f
, 2.0f
, 0.0f
, 0.0f
,
11124 0.0f
, 0.0f
, 2.0f
, 0.0f
,
11125 0.0f
, 0.0f
, 0.0f
, 1.0f
,
11129 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11130 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11131 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11132 1.0f
, 0.0f
, 0.0f
, 1.0f
,
11136 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11137 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11138 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11139 0.0f
, 1.0f
, 0.0f
, 1.0f
,
11143 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11144 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11145 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11146 0.0f
, 19.2f
, 0.0f
, 2.0f
,
11150 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11151 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11152 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11153 0.0f
, 0.0f
, 0.0f
, 1.0f
,
11155 static D3DLVERTEX quad
[] =
11157 {{-0.75f
},{-0.5f
}, {0.0f
}, 0, {0xffff0000}},
11158 {{-0.75f
},{ 0.25f
}, {0.0f
}, 0, {0xffff0000}},
11159 {{ 0.5f
}, {-0.5f
}, {0.0f
}, 0, {0xffff0000}},
11160 {{ 0.5f
}, { 0.25f
}, {0.0f
}, 0, {0xffff0000}},
11162 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
11165 for (i
= 0; i
< ARRAY_SIZE(out
); ++i
)
11167 out
[i
].unused3
= 0xdeadbeef;
11168 out
[i
].unused4
= 0xcafecafe;
11171 window
= create_window();
11172 ddraw
= create_ddraw();
11173 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11174 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
11176 skip("Failed to create a 3D device, skipping test.\n");
11177 IDirectDraw2_Release(ddraw
);
11178 DestroyWindow(window
);
11181 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
11182 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
11184 viewport
= create_viewport(device
, 0, 0, 256, 256);
11185 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
11186 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
11188 memset(&transformdata
, 0, sizeof(transformdata
));
11189 transformdata
.dwSize
= sizeof(transformdata
);
11190 transformdata
.lpIn
= position_tests
;
11191 transformdata
.dwInSize
= sizeof(position_tests
[0]);
11192 transformdata
.lpOut
= out
;
11193 transformdata
.dwOutSize
= sizeof(out
[0]);
11194 transformdata
.lpHOut
= NULL
;
11196 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11197 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11198 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11199 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
11201 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11203 static const struct vec4 cmp
[] =
11205 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {129.0f
, 127.0f
, 1.0f
, 1.0f
}, {127.0f
, 129.0f
, -1.0f
, 1.0f
},
11206 {128.5f
, 127.5f
, 0.5f
, 1.0f
}, {127.5f
, 128.5f
, -0.5f
, 1.0f
}, {127.5f
, 128.5f
, 0.0f
, 1.0f
}
11209 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11210 "Vertex %u differs. Got %f %f %f %f.\n", i
,
11211 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11212 ok(out
[i
].v1
== position_tests
[i
].v1
&& out
[i
].v2
== position_tests
[i
].v2
11213 && out
[i
].v3
== position_tests
[i
].v3
&& out
[i
].v4
== position_tests
[i
].v4
,
11214 "Vertex %u payload is %u %u %u %u.\n", i
, out
[i
].v1
, out
[i
].v2
, out
[i
].v3
, out
[i
].v4
);
11215 ok(out
[i
].unused3
== 0xdeadbeef && out
[i
].unused4
== 0xcafecafe,
11216 "Vertex %u unused data is %#x, %#x.\n", i
, out
[i
].unused3
, out
[i
].unused4
);
11219 vp_data
= vp_template
;
11220 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
11221 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
11222 offscreen
= 0xdeadbeef;
11223 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11224 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11225 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11226 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
11228 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11230 static const struct vec4 cmp
[] =
11232 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {133.0f
, 123.0f
, 1.0f
, 1.0f
}, {123.0f
, 133.0f
, -1.0f
, 1.0f
},
11233 {130.5f
, 125.5f
, 0.5f
, 1.0f
}, {125.5f
, 130.5f
, -0.5f
, 1.0f
}, {125.5f
, 130.5f
, 0.0f
, 1.0f
}
11235 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11236 "Vertex %u differs. Got %f %f %f %f.\n", i
,
11237 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11242 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
11243 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
11244 offscreen
= 0xdeadbeef;
11245 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11246 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11247 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11248 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
11249 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11251 static const struct vec4 cmp
[] =
11253 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, {133.0f
, 153.0f
, -1.0f
, 1.0f
},
11254 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, {135.5f
, 150.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
11256 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11257 "Vertex %u differs. Got %f %f %f %f.\n", i
,
11258 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11261 transformdata
.lpHOut
= out_h
;
11262 offscreen
= 0xdeadbeef;
11263 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11264 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11265 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11266 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
11267 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11269 static const D3DHVERTEX cmp_h
[] =
11271 {0, { 0.0f
}, { 0.0f
}, { 0.0f
}}, {0, { 1.0f
}, { 1.0f
}, {1.0f
}},
11272 {D3DCLIP_FRONT
, {-1.0f
}, {-1.0f
}, {-1.0f
}}, {0, { 0.5f
}, { 0.5f
}, {0.5f
}},
11273 {D3DCLIP_FRONT
, {-0.5f
}, {-0.5f
}, {-0.5f
}}, {0, {-0.5f
}, {-0.5f
}, {0.0f
}}
11275 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
11276 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
11277 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
11278 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
11279 "HVertex %u differs. Got %#x %f %f %f.\n", i
,
11280 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
11282 /* No scheme has been found behind those return values. It seems to be
11283 * whatever data windows has when throwing the vertex away. Modify the
11284 * input test vertices to test this more. Depending on the input data
11285 * it can happen that the z coord gets written into y, or similar things. */
11288 static const struct vec4 cmp
[] =
11290 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, { -1.0f
, -1.0f
, 0.5f
, 1.0f
},
11291 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, { -0.5f
, -0.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
11293 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11294 "Vertex %u differs. Got %f %f %f %f.\n", i
,
11295 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11299 transformdata
.lpIn
= cliptest
;
11300 transformdata
.dwInSize
= sizeof(cliptest
[0]);
11301 offscreen
= 0xdeadbeef;
11302 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
11303 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11304 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11305 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
11306 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
11308 static const DWORD flags
[] =
11311 D3DCLIP_RIGHT
| D3DCLIP_BACK
| D3DCLIP_TOP
,
11313 D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,
11315 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
11318 vp_data
= vp_template
;
11319 vp_data
.dwWidth
= 10;
11320 vp_data
.dwHeight
= 480;
11321 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
11322 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
11323 offscreen
= 0xdeadbeef;
11324 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
11325 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11326 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11327 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
11328 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
11330 static const DWORD flags
[] =
11333 D3DCLIP_RIGHT
| D3DCLIP_BACK
,
11335 D3DCLIP_LEFT
| D3DCLIP_FRONT
,
11337 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
11340 vp_data
= vp_template
;
11341 vp_data
.dwWidth
= 256;
11342 vp_data
.dwHeight
= 256;
11343 vp_data
.dvScaleX
= 1;
11344 vp_data
.dvScaleY
= 1;
11345 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
11346 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
11347 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
11348 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11349 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11350 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
11351 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
11353 static const DWORD flags
[] =
11360 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
11363 /* Finally try to figure out how the DWORD dwOffscreen works.
11364 * It is a logical AND of the vertices' dwFlags members. */
11365 vp_data
= vp_template
;
11366 vp_data
.dwWidth
= 5;
11367 vp_data
.dwHeight
= 5;
11368 vp_data
.dvScaleX
= 10000.0f
;
11369 vp_data
.dvScaleY
= 10000.0f
;
11370 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
11371 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
11372 transformdata
.lpIn
= cliptest
;
11373 offscreen
= 0xdeadbeef;
11374 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
11375 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11376 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11377 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
11379 offscreen
= 0xdeadbeef;
11380 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
11381 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11382 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11383 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
11384 offscreen
= 0xdeadbeef;
11385 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
11386 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11387 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11388 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
11389 hr
= IDirect3DViewport2_TransformVertices(viewport
, 3,
11390 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11391 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11392 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
11394 transformdata
.lpIn
= cliptest
+ 1;
11395 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
11396 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11397 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11398 ok(offscreen
== (D3DCLIP_BACK
| D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
11400 transformdata
.lpIn
= cliptest
+ 2;
11401 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
11402 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11403 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11404 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
11405 offscreen
= 0xdeadbeef;
11406 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
11407 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11408 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11409 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
11411 transformdata
.lpIn
= cliptest
+ 3;
11412 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
11413 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11414 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11415 ok(offscreen
== (D3DCLIP_FRONT
| D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
11417 transformdata
.lpIn
= offscreentest
;
11418 transformdata
.dwInSize
= sizeof(offscreentest
[0]);
11419 vp_data
= vp_template
;
11420 vp_data
.dwWidth
= 257;
11421 vp_data
.dwHeight
= 257;
11422 vp_data
.dvScaleX
= 1.0f
;
11423 vp_data
.dvScaleY
= 1.0f
;
11424 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
11425 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
11426 offscreen
= 0xdeadbeef;
11427 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
11428 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11429 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11430 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
11432 vp_data
.dwWidth
= 256;
11433 vp_data
.dwHeight
= 256;
11434 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
11435 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
11436 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
11437 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11438 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11439 ok(offscreen
== D3DCLIP_RIGHT
, "Offscreen is %x.\n", offscreen
);
11441 /* Test the effect of Matrices.
11443 * Basically the x coordinate ends up as ((x + 1) * 2 + 0) * 5 and
11444 * y as ((y + 0) * 2 + 1) * 5. The 5 comes from dvScaleX/Y, 2 from
11445 * the view matrix and the +1's from the world and projection matrix. */
11448 vp_data
.dwWidth
= 256;
11449 vp_data
.dwHeight
= 256;
11450 vp_data
.dvScaleX
= 5.0f
;
11451 vp_data
.dvScaleY
= 5.0f
;
11452 vp_data
.dvMinZ
= 0.0f
;
11453 vp_data
.dvMaxZ
= 1.0f
;
11454 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
11455 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
11457 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_translate1
);
11458 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
11459 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_scale
);
11460 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
11461 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_translate2
);
11462 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
11464 transformdata
.lpIn
= position_tests
;
11465 transformdata
.dwInSize
= sizeof(position_tests
[0]);
11466 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11467 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11468 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11470 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11472 static const struct vec4 cmp
[] =
11474 {138.0f
, 123.0f
, 0.0f
, 1.0f
}, {148.0f
, 113.0f
, 2.0f
, 1.0f
}, {128.0f
, 133.0f
, -2.0f
, 1.0f
},
11475 {143.0f
, 118.0f
, 1.0f
, 1.0f
}, {133.0f
, 128.0f
, -1.0f
, 1.0f
}, {133.0f
, 128.0f
, 0.0f
, 1.0f
}
11478 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11479 "Vertex %u differs. Got %f %f %f %f.\n", i
,
11480 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11483 /* Invalid flags. */
11484 offscreen
= 0xdeadbeef;
11485 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11486 &transformdata
, 0, &offscreen
);
11487 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
11488 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
11490 /* NULL transform data. */
11491 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
11492 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11493 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
11494 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
11495 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
11496 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11497 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
11498 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
11500 /* NULL transform data and NULL dwOffscreen.
11502 * Valid transform data + NULL dwOffscreen -> crash. */
11503 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
11504 NULL
, D3DTRANSFORM_UNCLIPPED
, NULL
);
11505 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
11508 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
11509 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11510 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11511 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
11512 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
11513 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11514 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11515 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
11517 /* Invalid sizes. */
11518 offscreen
= 0xdeadbeef;
11519 transformdata
.dwSize
= sizeof(transformdata
) - 1;
11520 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
11521 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11522 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
11523 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
11524 transformdata
.dwSize
= sizeof(transformdata
) + 1;
11525 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
11526 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11527 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
11528 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
11530 /* NULL lpIn or lpOut -> crash, except when transforming 0 vertices. */
11531 transformdata
.dwSize
= sizeof(transformdata
);
11532 transformdata
.lpIn
= NULL
;
11533 transformdata
.lpOut
= NULL
;
11534 offscreen
= 0xdeadbeef;
11535 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
11536 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11537 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11538 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
11540 /* Test how vertices are transformed during draws. */
11543 vp_data
.dwWidth
= 200;
11544 vp_data
.dwHeight
= 400;
11545 vp_data
.dvScaleX
= 20.0f
;
11546 vp_data
.dvScaleY
= 50.0f
;
11547 vp_data
.dvMinZ
= 0.0f
;
11548 vp_data
.dvMaxZ
= 1.0f
;
11549 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
11550 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
11551 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
11552 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
11554 ok(SUCCEEDED(hr
), "Failed to clear the render target, hr %#x.\n", hr
);
11555 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 0.0f
);
11556 viewport_set_background(device
, viewport
, background
);
11557 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11558 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
11560 hr
= IDirect3DDevice2_BeginScene(device
);
11561 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11562 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
11563 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11564 hr
= IDirect3DDevice2_EndScene(device
);
11565 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11567 color
= get_surface_color(rt
, 128, 143);
11568 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11569 color
= get_surface_color(rt
, 132, 143);
11570 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11571 color
= get_surface_color(rt
, 128, 147);
11572 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11573 color
= get_surface_color(rt
, 132, 147);
11574 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
11576 color
= get_surface_color(rt
, 177, 217);
11577 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
11578 color
= get_surface_color(rt
, 181, 217);
11579 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11580 color
= get_surface_color(rt
, 177, 221);
11581 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11582 color
= get_surface_color(rt
, 181, 221);
11583 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11585 /* Test D3DVIEWPORT2 behavior. */
11586 vp2_data
.dwSize
= sizeof(vp2_data
);
11589 vp2_data
.dwWidth
= 200;
11590 vp2_data
.dwHeight
= 400;
11591 vp2_data
.dvClipX
= -0.5f
;
11592 vp2_data
.dvClipY
= 4.0f
;
11593 vp2_data
.dvClipWidth
= 5.0f
;
11594 vp2_data
.dvClipHeight
= 10.0f
;
11595 vp2_data
.dvMinZ
= 0.0f
;
11596 vp2_data
.dvMaxZ
= 2.0f
;
11597 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp2_data
);
11598 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
11599 transformdata
.lpIn
= position_tests
;
11600 transformdata
.lpOut
= out
;
11601 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11602 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11603 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11604 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11606 static const struct vec4 cmp
[] =
11608 {120.0f
, 140.0f
, 0.0f
, 1.0f
}, {200.0f
, 60.0f
, 1.0f
, 1.0f
}, {40.0f
, 220.0f
, -1.0f
, 1.0f
},
11609 {160.0f
, 100.0f
, 0.5f
, 1.0f
}, { 80.0f
, 180.0f
, -0.5f
, 1.0f
}, {80.0f
, 180.0f
, 0.0f
, 1.0f
}
11612 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11613 "Vertex %u differs. Got %f %f %f %f.\n", i
,
11614 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11617 memset(&mat
, 0, sizeof(mat
));
11618 mat
.dwSize
= sizeof(mat
);
11619 U1(U(mat
).diffuse
).r
= 0.0f
;
11620 U2(U(mat
).diffuse
).g
= 1.0f
;
11621 U3(U(mat
).diffuse
).b
= 0.0f
;
11622 U4(U(mat
).diffuse
).a
= 0.0f
;
11623 hr
= IDirect3DMaterial2_SetMaterial(background
, &mat
);
11624 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
11625 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11626 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
11628 hr
= IDirect3DDevice2_BeginScene(device
);
11629 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11630 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
11631 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11632 hr
= IDirect3DDevice2_EndScene(device
);
11633 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11635 color
= get_surface_color(rt
, 58, 118);
11636 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
11637 color
= get_surface_color(rt
, 62, 118);
11638 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
11639 color
= get_surface_color(rt
, 58, 122);
11640 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
11641 color
= get_surface_color(rt
, 62, 122);
11642 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
11644 color
= get_surface_color(rt
, 157, 177);
11645 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
11646 color
= get_surface_color(rt
, 161, 177);
11647 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
11648 color
= get_surface_color(rt
, 157, 181);
11649 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
11650 color
= get_surface_color(rt
, 161, 181);
11651 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
11653 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_identity
);
11654 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
11655 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_identity
);
11656 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
11657 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_transform3
);
11658 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
11660 vp2_data
.dwX
= 0.0;
11661 vp2_data
.dwY
= 0.0;
11662 vp2_data
.dwWidth
= 1;
11663 vp2_data
.dwHeight
= 1;
11664 vp2_data
.dvClipX
= -12.8f
;
11665 vp2_data
.dvClipY
= 12.8f
+ mat_transform3
._42
/ mat_transform3
._44
;
11666 vp2_data
.dvClipWidth
= 25.6f
;
11667 vp2_data
.dvClipHeight
= 25.6f
;
11668 vp2_data
.dvMinZ
= 0.0f
;
11669 vp2_data
.dvMaxZ
= 0.5f
;
11670 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp2_data
);
11671 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
11672 transformdata
.lpIn
= cliptest
;
11673 transformdata
.dwInSize
= sizeof(cliptest
[0]);
11674 offscreen
= 0xdeadbeef;
11675 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
11676 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11677 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
11678 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
11679 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
11681 static const D3DHVERTEX cmp_h
[] =
11683 {0, { 25.59f
}, { 44.79f
}, { 1.0f
}},
11684 {D3DCLIP_RIGHT
| D3DCLIP_TOP
| D3DCLIP_BACK
, { 25.61f
}, { 44.81f
}, { 1.01f
}},
11685 {0, {-25.59f
}, {-6.39f
}, { 0.0f
}},
11686 {D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,{-25.61f
}, {-6.41f
}, {-0.01f
}},
11688 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
11689 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
11690 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
11691 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
11692 "HVertex %u differs. Got %#x %f %f %f.\n", i
,
11693 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
11696 IDirectDrawSurface_Release(rt
);
11697 destroy_viewport(device
, viewport
);
11698 IDirect3DMaterial2_Release(background
);
11699 refcount
= IDirect3DDevice_Release(device
);
11700 ok(!refcount
, "Device has %u references left.\n", refcount
);
11701 IDirectDraw2_Release(ddraw
);
11702 DestroyWindow(window
);
11705 static void test_display_mode_surface_pixel_format(void)
11707 unsigned int width
, height
, bpp
;
11708 IDirectDrawSurface
*surface
;
11709 DDSURFACEDESC surface_desc
;
11710 IDirectDraw2
*ddraw
;
11715 if (!(ddraw
= create_ddraw()))
11717 skip("Failed to create ddraw.\n");
11721 surface_desc
.dwSize
= sizeof(surface_desc
);
11722 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
11723 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
11724 width
= surface_desc
.dwWidth
;
11725 height
= surface_desc
.dwHeight
;
11727 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
11728 0, 0, width
, height
, NULL
, NULL
, NULL
, NULL
);
11729 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
11730 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11733 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 16, 0, 0)))
11735 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0)))
11737 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
11739 ok(bpp
, "Set display mode failed.\n");
11741 surface_desc
.dwSize
= sizeof(surface_desc
);
11742 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
11743 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
11744 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
11745 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
11746 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
11747 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
11749 memset(&surface_desc
, 0, sizeof(surface_desc
));
11750 surface_desc
.dwSize
= sizeof(surface_desc
);
11751 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
11752 surface_desc
.dwBackBufferCount
= 1;
11753 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_PRIMARYSURFACE
;
11754 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11755 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
11756 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
11757 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
11758 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
11759 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
11760 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
11761 surface_desc
.ddpfPixelFormat
.dwFlags
);
11762 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
11763 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
11764 IDirectDrawSurface_Release(surface
);
11766 memset(&surface_desc
, 0, sizeof(surface_desc
));
11767 surface_desc
.dwSize
= sizeof(surface_desc
);
11768 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
11769 surface_desc
.dwWidth
= width
;
11770 surface_desc
.dwHeight
= height
;
11771 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11772 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11773 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
11774 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
11775 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
11776 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
11777 surface_desc
.ddpfPixelFormat
.dwFlags
);
11778 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
11779 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
11780 IDirectDrawSurface_Release(surface
);
11782 refcount
= IDirectDraw2_Release(ddraw
);
11783 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
11784 DestroyWindow(window
);
11787 static void test_surface_desc_size(void)
11792 DDSURFACEDESC desc1
;
11793 DDSURFACEDESC2 desc2
;
11796 IDirectDrawSurface7
*surface7
;
11797 IDirectDrawSurface2
*surface2
;
11798 IDirectDrawSurface
*surface
;
11799 DDSURFACEDESC surface_desc
;
11800 HRESULT expected_hr
, hr
;
11801 IDirectDraw2
*ddraw
;
11805 static const struct
11812 {DDSCAPS_OFFSCREENPLAIN
, "offscreenplain"},
11813 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "systemmemory texture"},
11814 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "videomemory texture"},
11816 static const unsigned int desc_sizes
[] =
11818 sizeof(DDSURFACEDESC
),
11819 sizeof(DDSURFACEDESC2
),
11820 sizeof(DDSURFACEDESC
) + 1,
11821 sizeof(DDSURFACEDESC2
) + 1,
11822 2 * sizeof(DDSURFACEDESC
),
11823 2 * sizeof(DDSURFACEDESC2
),
11824 sizeof(DDSURFACEDESC
) - 1,
11825 sizeof(DDSURFACEDESC2
) - 1,
11826 sizeof(DDSURFACEDESC
) / 2,
11827 sizeof(DDSURFACEDESC2
) / 2,
11832 sizeof(desc
) - 100,
11835 if (!(ddraw
= create_ddraw()))
11837 skip("Failed to create ddraw.\n");
11840 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
11841 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11843 for (i
= 0; i
< ARRAY_SIZE(surface_caps
); ++i
)
11845 memset(&surface_desc
, 0, sizeof(surface_desc
));
11846 surface_desc
.dwSize
= sizeof(surface_desc
);
11847 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
11848 surface_desc
.ddsCaps
.dwCaps
= surface_caps
[i
].caps
;
11849 surface_desc
.dwHeight
= 128;
11850 surface_desc
.dwWidth
= 128;
11851 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11853 skip("Failed to create surface, type %s.\n", surface_caps
[i
].name
);
11856 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface2
, (void **)&surface2
);
11857 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface2, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
11858 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface7
, (void **)&surface7
);
11859 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface7, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
11861 /* GetSurfaceDesc() */
11862 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
11864 memset(&desc
, 0, sizeof(desc
));
11865 desc
.dwSize
= desc_sizes
[j
];
11866 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
11867 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
.desc1
);
11868 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
11869 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11871 memset(&desc
, 0, sizeof(desc
));
11872 desc
.dwSize
= desc_sizes
[j
];
11873 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
11874 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface2
, &desc
.desc1
);
11875 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
11876 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11878 memset(&desc
, 0, sizeof(desc
));
11879 desc
.dwSize
= desc_sizes
[j
];
11880 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC2
) ? DD_OK
: DDERR_INVALIDPARAMS
;
11881 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface7
, &desc
.desc2
);
11882 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
11883 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11887 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
11889 const BOOL valid_size
= desc_sizes
[j
] == sizeof(DDSURFACEDESC
)
11890 || desc_sizes
[j
] == sizeof(DDSURFACEDESC2
);
11891 DWORD expected_texture_stage
;
11893 memset(&desc
, 0, sizeof(desc
));
11894 desc
.dwSize
= desc_sizes
[j
];
11895 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
11896 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
11897 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
.desc1
, 0, 0);
11898 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
11899 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
11900 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11901 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
11902 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
11903 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
11904 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
11907 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
11908 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
11909 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
11910 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
11911 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
11912 todo_wine_if(!expected_texture_stage
)
11913 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
11914 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
11915 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
11916 IDirectDrawSurface_Unlock(surface
, NULL
);
11919 memset(&desc
, 0, sizeof(desc
));
11920 desc
.dwSize
= desc_sizes
[j
];
11921 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
11922 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
11923 hr
= IDirectDrawSurface2_Lock(surface2
, NULL
, &desc
.desc1
, 0, 0);
11924 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
11925 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
11926 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11927 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
11928 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
11929 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
11930 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
11933 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
11934 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
11935 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
11936 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
11937 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
11938 todo_wine_if(!expected_texture_stage
)
11939 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
11940 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
11941 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
11942 IDirectDrawSurface2_Unlock(surface2
, NULL
);
11945 memset(&desc
, 0, sizeof(desc
));
11946 desc
.dwSize
= desc_sizes
[j
];
11947 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
11948 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
11949 hr
= IDirectDrawSurface7_Lock(surface7
, NULL
, &desc
.desc2
, 0, 0);
11950 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
11951 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
11952 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11953 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
11954 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
11955 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
11956 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
11959 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
11960 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
11961 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
11962 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
11963 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
11964 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
11965 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
11966 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
11967 IDirectDrawSurface7_Unlock(surface7
, NULL
);
11971 IDirectDrawSurface7_Release(surface7
);
11972 IDirectDrawSurface2_Release(surface2
);
11973 IDirectDrawSurface_Release(surface
);
11976 /* GetDisplayMode() */
11977 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
11979 memset(&desc
, 0xcc, sizeof(desc
));
11980 desc
.dwSize
= desc_sizes
[j
];
11981 expected_hr
= (desc
.dwSize
== sizeof(DDSURFACEDESC
) || desc
.dwSize
== sizeof(DDSURFACEDESC2
))
11982 ? DD_OK
: DDERR_INVALIDPARAMS
;
11983 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &desc
.desc1
);
11984 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, size %u.\n", hr
, expected_hr
, desc_sizes
[j
]);
11987 ok(desc
.dwSize
== sizeof(DDSURFACEDESC
), "Wrong size %u for %u.\n", desc
.dwSize
, desc_sizes
[j
]);
11988 ok(desc
.blob
[desc_sizes
[j
]] == 0xcc, "Overflow for size %u.\n", desc_sizes
[j
]);
11989 ok(desc
.blob
[desc_sizes
[j
] - 1] != 0xcc, "Struct not cleared for size %u.\n", desc_sizes
[j
]);
11993 refcount
= IDirectDraw2_Release(ddraw
);
11994 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
11997 static void test_ck_operation(void)
11999 IDirectDrawSurface2
*src
, *dst
;
12000 IDirectDrawSurface7
*src7
, *dst7
;
12001 IDirectDrawSurface
*surface1
;
12002 DDSURFACEDESC surface_desc
;
12003 IDirectDraw2
*ddraw
;
12012 window
= create_window();
12013 ddraw
= create_ddraw();
12014 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12015 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12016 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12018 memset(&surface_desc
, 0, sizeof(surface_desc
));
12019 surface_desc
.dwSize
= sizeof(surface_desc
);
12020 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12021 surface_desc
.dwWidth
= 4;
12022 surface_desc
.dwHeight
= 1;
12023 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12024 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12025 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
12026 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
12027 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
12028 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
12029 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
12030 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
12031 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&dst
);
12032 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#x.\n", hr
);
12033 IDirectDrawSurface_Release(surface1
);
12035 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
12036 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff00ff;
12037 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff00ff;
12038 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
12039 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
12040 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&src
);
12041 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#x.\n", hr
);
12042 IDirectDrawSurface_Release(surface1
);
12044 hr
= IDirectDrawSurface2_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12045 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12046 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
12047 color
= surface_desc
.lpSurface
;
12048 color
[0] = 0x77010203;
12049 color
[1] = 0x00010203;
12050 color
[2] = 0x77ff00ff;
12051 color
[3] = 0x00ff00ff;
12052 hr
= IDirectDrawSurface2_Unlock(src
, NULL
);
12053 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12055 for (i
= 0; i
< 2; ++i
)
12057 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12058 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12059 color
= surface_desc
.lpSurface
;
12060 color
[0] = 0xcccccccc;
12061 color
[1] = 0xcccccccc;
12062 color
[2] = 0xcccccccc;
12063 color
[3] = 0xcccccccc;
12064 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12065 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12069 hr
= IDirectDrawSurface2_BltFast(dst
, 0, 0, src
, NULL
, DDBLTFAST_SRCCOLORKEY
);
12070 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
12074 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, NULL
);
12075 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
12078 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
| DDLOCK_READONLY
, NULL
);
12079 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12080 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
12081 color
= surface_desc
.lpSurface
;
12082 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
12083 * color keying, but copy it to the destination surface. Others (sysmem surfaces) apply it for
12084 * color keying, but do not copy it into the destination surface. Nvidia neither uses it for
12085 * color keying nor copies it. */
12086 ok((color
[0] == 0x77010203 && color
[1] == 0x00010203
12087 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* AMD, Wine */
12088 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
12089 && color
[2] == 0x00ff00ff && color
[3] == 0xcccccccc) /* Sysmem surfaces? */
12090 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
12091 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Nvidia */
12092 || broken(color
[0] == 0xff010203 && color
[1] == 0xff010203
12093 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Testbot */,
12094 "Destination data after blitting is %08x %08x %08x %08x, i=%u.\n",
12095 color
[0], color
[1], color
[2], color
[3], i
);
12096 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12097 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12100 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12101 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12102 ok(ckey
.dwColorSpaceLowValue
== 0x00ff00ff && ckey
.dwColorSpaceHighValue
== 0x00ff00ff,
12103 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12105 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
12106 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12107 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12109 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12110 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12111 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12112 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00 && ckey
.dwColorSpaceHighValue
== 0x0000ff00,
12113 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12115 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0;
12116 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0;
12117 hr
= IDirectDrawSurface2_GetSurfaceDesc(src
, &surface_desc
);
12118 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
12119 ok(surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0x0000ff00
12120 && surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0x0000ff00,
12121 "Got unexpected color key low=%08x high=%08x.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
12122 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
12124 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
12125 ckey
.dwColorSpaceLowValue
= 0x000000ff;
12126 ckey
.dwColorSpaceHighValue
= 0x00000000;
12127 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12128 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12130 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12131 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12132 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12133 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
12134 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12136 ckey
.dwColorSpaceLowValue
= 0x000000ff;
12137 ckey
.dwColorSpaceHighValue
= 0x00000001;
12138 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12139 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12141 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12142 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12143 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12144 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
12145 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12147 ckey
.dwColorSpaceLowValue
= 0x000000fe;
12148 ckey
.dwColorSpaceHighValue
= 0x000000fd;
12149 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12150 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12152 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12153 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12154 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12155 ok(ckey
.dwColorSpaceLowValue
== 0x000000fe && ckey
.dwColorSpaceHighValue
== 0x000000fe,
12156 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12158 IDirectDrawSurface2_Release(src
);
12159 IDirectDrawSurface2_Release(dst
);
12161 /* Test source and destination keys and where they are read from. Use a surface with alpha
12162 * to avoid driver-dependent content in the X channel. */
12163 memset(&surface_desc
, 0, sizeof(surface_desc
));
12164 surface_desc
.dwSize
= sizeof(surface_desc
);
12165 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12166 surface_desc
.dwWidth
= 6;
12167 surface_desc
.dwHeight
= 1;
12168 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12169 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
12170 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
12171 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
12172 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
12173 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
12174 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
12175 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
12176 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
12177 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&dst
);
12178 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#x.\n", hr
);
12179 IDirectDrawSurface_Release(surface1
);
12181 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
12182 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
12183 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&src
);
12184 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#x.\n", hr
);
12185 IDirectDrawSurface_Release(surface1
);
12187 ckey
.dwColorSpaceLowValue
= 0x0000ff00;
12188 ckey
.dwColorSpaceHighValue
= 0x0000ff00;
12189 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
12190 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12191 ckey
.dwColorSpaceLowValue
= 0x00ff0000;
12192 ckey
.dwColorSpaceHighValue
= 0x00ff0000;
12193 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_DESTBLT
, &ckey
);
12194 ok(SUCCEEDED(hr
) || hr
== DDERR_NOCOLORKEYHW
, "Failed to set color key, hr %#x.\n", hr
);
12197 /* Nvidia reject dest keys, AMD allows them. This applies to vidmem and sysmem surfaces. */
12198 skip("Failed to set destination color key, skipping related tests.\n");
12202 ckey
.dwColorSpaceLowValue
= 0x000000ff;
12203 ckey
.dwColorSpaceHighValue
= 0x000000ff;
12204 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12205 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12206 ckey
.dwColorSpaceLowValue
= 0x000000aa;
12207 ckey
.dwColorSpaceHighValue
= 0x000000aa;
12208 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
12209 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12211 memset(&fx
, 0, sizeof(fx
));
12212 fx
.dwSize
= sizeof(fx
);
12213 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x00110000;
12214 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x00110000;
12215 fx
.ddckDestColorkey
.dwColorSpaceHighValue
= 0x00001100;
12216 fx
.ddckDestColorkey
.dwColorSpaceLowValue
= 0x00001100;
12218 hr
= IDirectDrawSurface2_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12219 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12220 color
= surface_desc
.lpSurface
;
12221 color
[0] = 0x000000ff; /* Applies to src blt key in src surface. */
12222 color
[1] = 0x000000aa; /* Applies to dst blt key in src surface. */
12223 color
[2] = 0x00ff0000; /* Dst color key in dst surface. */
12224 color
[3] = 0x0000ff00; /* Src color key in dst surface. */
12225 color
[4] = 0x00001100; /* Src color key in ddbltfx. */
12226 color
[5] = 0x00110000; /* Dst color key in ddbltfx. */
12227 hr
= IDirectDrawSurface2_Unlock(src
, NULL
);
12228 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12230 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12231 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12232 color
= surface_desc
.lpSurface
;
12233 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
12234 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12235 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12237 /* Test a blit without keying. */
12238 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, 0, &fx
);
12239 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
12241 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12242 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12243 color
= surface_desc
.lpSurface
;
12244 /* Should have copied src data unmodified to dst. */
12245 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
12246 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12247 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12248 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12250 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
12251 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12252 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12255 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
12256 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
12258 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12259 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12260 color
= surface_desc
.lpSurface
;
12261 /* Src key applied to color[0]. It is unmodified, the others are copied. */
12262 ok(color
[0] == 0x55555555 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
12263 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12264 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12265 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12267 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
12268 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12269 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12271 /* Src override. */
12272 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, &fx
);
12273 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
12275 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12276 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12277 color
= surface_desc
.lpSurface
;
12278 /* Override key applied to color[5]. It is unmodified, the others are copied. */
12279 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
12280 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x55555555,
12281 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12282 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12284 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
12285 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12286 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12288 /* Src override AND src key. That is not supposed to work. */
12289 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_KEYSRCOVERRIDE
, &fx
);
12290 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
12292 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12293 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12294 color
= surface_desc
.lpSurface
;
12295 /* Ensure the destination was not changed. */
12296 ok(color
[0] == 0x55555555 && color
[1] == 0x55555555 && color
[2] == 0x55555555 &&
12297 color
[3] == 0x55555555 && color
[4] == 0x55555555 && color
[5] == 0x55555555,
12298 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12299 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12301 /* Use different dst colors for the dst key test. */
12302 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12303 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12304 color
[2] = 0x00001100; /* Dest key in override. */
12305 color
[3] = 0x00001100; /* Dest key in override. */
12306 color
[4] = 0x000000aa; /* Dest key in src surface. */
12307 color
[5] = 0x000000aa; /* Dest key in src surface. */
12308 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12309 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12311 /* Dest key blit. The key is taken from the SOURCE surface in v2! */
12312 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
12313 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
12315 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12316 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12317 color
= surface_desc
.lpSurface
;
12318 /* Dst key applied to color[4,5], they are the only changed pixels. */
12319 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
12320 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12321 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12322 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12324 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12325 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12326 color
[2] = 0x00001100; /* Dest key in override. */
12327 color
[3] = 0x00001100; /* Dest key in override. */
12328 color
[4] = 0x000000aa; /* Dest key in src surface. */
12329 color
[5] = 0x000000aa; /* Dest key in src surface. */
12330 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12331 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12333 /* What happens with a QI'd newer version of the interface? It takes the key
12334 * from the destination surface. */
12335 hr
= IDirectDrawSurface2_QueryInterface(src
, &IID_IDirectDrawSurface7
, (void **)&src7
);
12336 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
12337 hr
= IDirectDrawSurface2_QueryInterface(dst
, &IID_IDirectDrawSurface7
, (void **)&dst7
);
12338 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
12340 hr
= IDirectDrawSurface7_Blt(dst7
, NULL
, src7
, NULL
, DDBLT_KEYDEST
, &fx
);
12341 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
12343 IDirectDrawSurface7_Release(dst7
);
12344 IDirectDrawSurface7_Release(src7
);
12346 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12347 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12348 color
= surface_desc
.lpSurface
;
12349 /* Dst key applied to color[0,1], they are the only changed pixels. */
12350 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
12351 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
12352 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12353 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12355 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12356 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12357 color
[2] = 0x00001100; /* Dest key in override. */
12358 color
[3] = 0x00001100; /* Dest key in override. */
12359 color
[4] = 0x000000aa; /* Dest key in src surface. */
12360 color
[5] = 0x000000aa; /* Dest key in src surface. */
12361 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12362 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12364 /* Dest override key blit. */
12365 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, &fx
);
12366 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
12368 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12369 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12370 color
= surface_desc
.lpSurface
;
12371 /* Dst key applied to color[2,3], they are the only changed pixels. */
12372 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00ff0000 &&
12373 color
[3] == 0x0000ff00 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
12374 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12375 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12377 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12378 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12379 color
[2] = 0x00001100; /* Dest key in override. */
12380 color
[3] = 0x00001100; /* Dest key in override. */
12381 color
[4] = 0x000000aa; /* Dest key in src surface. */
12382 color
[5] = 0x000000aa; /* Dest key in src surface. */
12383 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12384 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12386 /* Dest override together with surface key. Supposed to fail. */
12387 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYDESTOVERRIDE
, &fx
);
12388 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
12390 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12391 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12392 color
= surface_desc
.lpSurface
;
12393 /* Destination is unchanged. */
12394 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
12395 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
12396 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12397 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12398 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12399 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12401 /* Source and destination key. This is driver dependent. New HW treats it like
12402 * DDBLT_KEYSRC. Older HW and some software renderers apply both keys. */
12405 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYSRC
, &fx
);
12406 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
12408 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12409 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12410 color
= surface_desc
.lpSurface
;
12411 /* Color[0] is filtered by the src key, 2-5 are filtered by the dst key, if
12412 * the driver applies it. */
12413 ok(color
[0] == 0x00ff0000 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
12414 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12415 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12416 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12418 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12419 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12420 color
[2] = 0x00001100; /* Dest key in override. */
12421 color
[3] = 0x00001100; /* Dest key in override. */
12422 color
[4] = 0x000000aa; /* Dest key in src surface. */
12423 color
[5] = 0x000000aa; /* Dest key in src surface. */
12424 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12425 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12428 /* Override keys without ddbltfx parameter fail */
12429 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, NULL
);
12430 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
12431 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, NULL
);
12432 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
12434 /* Try blitting without keys in the source surface. */
12435 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
12436 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12437 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_DESTBLT
, NULL
);
12438 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12440 /* That fails now. Do not bother to check that the data is unmodified. */
12441 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
12442 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
12444 /* Surprisingly this still works. It uses the old key from the src surface. */
12445 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
12446 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
12448 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12449 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12450 color
= surface_desc
.lpSurface
;
12451 /* Dst key applied to color[4,5], they are the only changed pixels. */
12452 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
12453 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12454 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12455 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12456 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12457 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12459 /* This returns DDERR_NOCOLORKEY as expected. */
12460 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
12461 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
12463 /* GetSurfaceDesc returns a zeroed key as expected. */
12464 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x12345678;
12465 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x12345678;
12466 hr
= IDirectDrawSurface2_GetSurfaceDesc(src
, &surface_desc
);
12467 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
12468 ok(!surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
12469 && !surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
,
12470 "Got unexpected color key low=%08x high=%08x.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
12471 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
12473 /* Try blitting without keys in the destination surface. */
12474 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_SRCBLT
, NULL
);
12475 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12476 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_DESTBLT
, NULL
);
12477 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12479 /* This fails, as sanity would dictate. */
12480 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
12481 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
12484 IDirectDrawSurface2_Release(src
);
12485 IDirectDrawSurface2_Release(dst
);
12486 refcount
= IDirectDraw2_Release(ddraw
);
12487 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
12488 DestroyWindow(window
);
12491 static void test_set_render_state(void)
12493 IDirect3DDevice2
*device
;
12494 IDirectDraw2
*ddraw
;
12500 window
= create_window();
12501 ddraw
= create_ddraw();
12502 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12503 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
12505 skip("Failed to create 3D device.\n");
12506 DestroyWindow(window
);
12510 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, TRUE
);
12511 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
12512 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, FALSE
);
12513 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
12515 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
12516 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
12517 state
= 0xdeadbeef;
12518 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, &state
);
12519 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
12520 ok(!state
, "Got unexpected render state %#x.\n", state
);
12521 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
12522 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
12523 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &state
);
12524 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
12525 ok(state
== D3DTBLEND_MODULATE
, "Got unexpected render state %#x.\n", state
);
12527 refcount
= IDirect3DDevice2_Release(device
);
12528 ok(!refcount
, "Device has %u references left.\n", refcount
);
12529 refcount
= IDirectDraw2_Release(ddraw
);
12530 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
12531 DestroyWindow(window
);
12534 static void test_depth_readback(void)
12536 DWORD depth
, expected_depth
, max_diff
, passed_fmts
= 0;
12537 IDirect3DMaterial2
*blue_background
;
12538 IDirectDrawSurface
*rt
, *ds
;
12539 IDirect3DViewport2
*viewport
;
12540 DDSURFACEDESC surface_desc
;
12541 IDirect3DDevice2
*device
;
12542 unsigned int i
, x
, y
;
12543 IDirectDraw2
*ddraw
;
12550 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12551 static D3DLVERTEX quad
[] =
12553 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xff00ff00}},
12554 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
12555 {{ 1.0f
}, {-1.0f
}, {1.0f
}, 0, {0xff00ff00}},
12556 {{ 1.0f
}, { 1.0f
}, {0.9f
}, 0, {0xff00ff00}},
12559 static const struct
12561 unsigned int z_depth
, z_mask
;
12570 window
= create_window();
12571 ok(!!window
, "Failed to create a window.\n");
12572 ddraw
= create_ddraw();
12573 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12574 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
12576 skip("Failed to create a D3D device, skipping tests.\n");
12577 IDirectDraw2_Release(ddraw
);
12578 DestroyWindow(window
);
12582 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
12583 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
12584 blue_background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
12585 viewport
= create_viewport(device
, 0, 0, 640, 480);
12586 viewport_set_background(device
, viewport
, blue_background
);
12587 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
12588 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
12590 ds
= get_depth_stencil(device
);
12591 hr
= IDirectDrawSurface_DeleteAttachedSurface(rt
, 0, ds
);
12592 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
12593 IDirectDrawSurface_Release(ds
);
12595 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
12597 memset(&surface_desc
, 0, sizeof(surface_desc
));
12598 surface_desc
.dwSize
= sizeof(surface_desc
);
12599 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
12600 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
;
12601 U2(surface_desc
).dwZBufferBitDepth
= tests
[i
].z_depth
;
12602 surface_desc
.dwWidth
= 640;
12603 surface_desc
.dwHeight
= 480;
12604 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
12607 skip("Format %u not supported, skipping test.\n", i
);
12611 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
12612 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
12613 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
12614 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
12616 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
12617 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
12618 hr
= IDirect3DDevice2_BeginScene(device
);
12619 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12620 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
12621 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12622 hr
= IDirect3DDevice2_EndScene(device
);
12623 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12625 memset(&surface_desc
, 0, sizeof(surface_desc
));
12626 surface_desc
.dwSize
= sizeof(surface_desc
);
12627 hr
= IDirectDrawSurface_Lock(ds
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12628 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12631 for (y
= 60; y
< 480; y
+= 120)
12633 for (x
= 80; x
< 640; x
+= 160)
12635 ptr
= (BYTE
*)surface_desc
.lpSurface
12636 + y
* U1(surface_desc
).lPitch
12637 + x
* (tests
[i
].z_depth
== 16 ? 2 : 4);
12638 depth
= *((DWORD
*)ptr
) & tests
[i
].z_mask
;
12639 expected_depth
= (x
* (0.9 / 640.0) + y
* (0.1 / 480.0)) * tests
[i
].z_mask
;
12640 max_diff
= ((0.5f
* 0.9f
) / 640.0f
) * tests
[i
].z_mask
;
12641 /* The ddraw2 version of this test behaves similarly to the ddraw7 version on Nvidia GPUs,
12642 * except that we only have D16 (broken on geforce 9) and D24X8 (broken on geforce 7) available.
12643 * Accept all nvidia GPUs as broken here, but still expect one of the formats to pass. */
12644 ok(abs(expected_depth
- depth
) <= max_diff
|| ddraw_is_nvidia(ddraw
),
12645 "Test %u: Got depth 0x%08x (diff %d), expected 0x%08x+/-%u, at %u, %u.\n",
12646 i
, depth
, expected_depth
- depth
, expected_depth
, max_diff
, x
, y
);
12647 if (abs(expected_depth
- depth
) > max_diff
)
12652 hr
= IDirectDrawSurface_Unlock(ds
, NULL
);
12653 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12658 hr
= IDirectDrawSurface_DeleteAttachedSurface(rt
, 0, ds
);
12659 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
12660 IDirectDrawSurface_Release(ds
);
12663 ok(passed_fmts
, "Not a single format passed the tests, this is bad even by Nvidia's standards.\n");
12665 destroy_viewport(device
, viewport
);
12666 destroy_material(blue_background
);
12667 IDirectDrawSurface_Release(rt
);
12668 refcount
= IDirect3DDevice2_Release(device
);
12669 ok(!refcount
, "Device has %u references left.\n", refcount
);
12670 IDirectDraw2_Release(ddraw
);
12671 DestroyWindow(window
);
12674 static void test_clear(void)
12676 D3DRECT rect_negneg
, rect_full
= {{0}, {0}, {640}, {480}};
12677 IDirect3DViewport2
*viewport
, *viewport2
, *viewport3
;
12678 IDirect3DMaterial2
*white
, *red
, *green
, *blue
;
12679 IDirect3DDevice2
*device
;
12680 IDirectDrawSurface
*rt
;
12681 IDirectDraw2
*ddraw
;
12688 window
= create_window();
12689 ddraw
= create_ddraw();
12690 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12691 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
12693 skip("Failed to create a 3D device, skipping test.\n");
12694 IDirectDraw2_Release(ddraw
);
12695 DestroyWindow(window
);
12698 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
12699 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
12701 viewport
= create_viewport(device
, 0, 0, 640, 480);
12702 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
12703 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
12705 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
12706 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
12707 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
12708 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
12710 viewport_set_background(device
, viewport
, white
);
12711 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
12712 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
12714 /* Positive x, negative y. */
12715 U1(rect
[0]).x1
= 0;
12716 U2(rect
[0]).y1
= 480;
12717 U3(rect
[0]).x2
= 320;
12718 U4(rect
[0]).y2
= 240;
12720 /* Positive x, positive y. */
12721 U1(rect
[1]).x1
= 0;
12722 U2(rect
[1]).y1
= 0;
12723 U3(rect
[1]).x2
= 320;
12724 U4(rect
[1]).y2
= 240;
12726 /* Clear 2 rectangles with one call. Unlike d3d8/9, the refrast does not
12727 * refuse negative rectangles, but it will not clear them either. */
12728 viewport_set_background(device
, viewport
, red
);
12729 hr
= IDirect3DViewport2_Clear(viewport
, 2, rect
, D3DCLEAR_TARGET
);
12730 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
12732 color
= get_surface_color(rt
, 160, 360);
12733 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 3 (pos, neg) has color 0x%08x.\n", color
);
12734 color
= get_surface_color(rt
, 160, 120);
12735 ok(compare_color(color
, 0x00ff0000, 0), "Clear rectangle 1 (pos, pos) has color 0x%08x.\n", color
);
12736 color
= get_surface_color(rt
, 480, 360);
12737 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (NULL) has color 0x%08x.\n", color
);
12738 color
= get_surface_color(rt
, 480, 120);
12739 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (neg, neg) has color 0x%08x.\n", color
);
12741 viewport_set_background(device
, viewport
, white
);
12742 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
12743 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
12745 /* negative x, negative y.
12746 * Also ignored, except on WARP, which clears the entire screen. */
12747 U1(rect_negneg
).x1
= 640;
12748 U2(rect_negneg
).y1
= 240;
12749 U3(rect_negneg
).x2
= 320;
12750 U4(rect_negneg
).y2
= 0;
12751 viewport_set_background(device
, viewport
, green
);
12752 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_negneg
, D3DCLEAR_TARGET
);
12753 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
12755 color
= get_surface_color(rt
, 160, 360);
12756 ok(compare_color(color
, 0x00ffffff, 0)
12757 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12758 "Got unexpected color 0x%08x.\n", color
);
12759 color
= get_surface_color(rt
, 160, 120);
12760 ok(compare_color(color
, 0x00ffffff, 0)
12761 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12762 "Got unexpected color 0x%08x.\n", color
);
12763 color
= get_surface_color(rt
, 480, 360);
12764 ok(compare_color(color
, 0x00ffffff, 0)
12765 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12766 "Got unexpected color 0x%08x.\n", color
);
12767 color
= get_surface_color(rt
, 480, 120);
12768 ok(compare_color(color
, 0x00ffffff, 0)
12769 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12770 "Got unexpected color 0x%08x.\n", color
);
12772 /* Test how the viewport affects clears. */
12773 viewport_set_background(device
, viewport
, white
);
12774 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
12775 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
12777 viewport2
= create_viewport(device
, 160, 120, 160, 120);
12778 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
12779 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
12781 viewport_set_background(device
, viewport2
, blue
);
12782 hr
= IDirect3DViewport2_Clear(viewport2
, 1, &rect_full
, D3DCLEAR_TARGET
);
12783 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
12785 viewport3
= create_viewport(device
, 320, 240, 320, 240);
12786 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport3
);
12787 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
12789 U1(rect
[0]).x1
= 160;
12790 U2(rect
[0]).y1
= 120;
12791 U3(rect
[0]).x2
= 480;
12792 U4(rect
[0]).y2
= 360;
12793 viewport_set_background(device
, viewport3
, green
);
12794 hr
= IDirect3DViewport2_Clear(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
);
12795 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
12797 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
12798 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
12800 color
= get_surface_color(rt
, 158, 118);
12801 ok(compare_color(color
, 0x00ffffff, 0), "(158, 118) has color 0x%08x.\n", color
);
12802 color
= get_surface_color(rt
, 162, 118);
12803 ok(compare_color(color
, 0x00ffffff, 0), "(162, 118) has color 0x%08x.\n", color
);
12804 color
= get_surface_color(rt
, 158, 122);
12805 ok(compare_color(color
, 0x00ffffff, 0), "(158, 122) has color 0x%08x.\n", color
);
12806 color
= get_surface_color(rt
, 162, 122);
12807 ok(compare_color(color
, 0x000000ff, 0), "(162, 122) has color 0x%08x.\n", color
);
12809 color
= get_surface_color(rt
, 318, 238);
12810 ok(compare_color(color
, 0x000000ff, 0), "(318, 238) has color 0x%08x.\n", color
);
12811 color
= get_surface_color(rt
, 322, 238);
12812 ok(compare_color(color
, 0x00ffffff, 0), "(322, 238) has color 0x%08x.\n", color
);
12813 color
= get_surface_color(rt
, 318, 242);
12814 ok(compare_color(color
, 0x00ffffff, 0), "(318, 242) has color 0x%08x.\n", color
);
12815 color
= get_surface_color(rt
, 322, 242);
12816 ok(compare_color(color
, 0x0000ff00, 0), "(322, 242) has color 0x%08x.\n", color
);
12818 color
= get_surface_color(rt
, 478, 358);
12819 ok(compare_color(color
, 0x0000ff00, 0), "(478, 358) has color 0x%08x.\n", color
);
12820 color
= get_surface_color(rt
, 482, 358);
12821 ok(compare_color(color
, 0x00ffffff, 0), "(482, 358) has color 0x%08x.\n", color
);
12822 color
= get_surface_color(rt
, 478, 362);
12823 ok(compare_color(color
, 0x00ffffff, 0), "(478, 362) has color 0x%08x.\n", color
);
12824 color
= get_surface_color(rt
, 482, 362);
12825 ok(compare_color(color
, 0x00ffffff, 0), "(482, 362) has color 0x%08x.\n", color
);
12827 /* The clear rectangle is rendertarget absolute, not relative to the
12829 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
12830 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
12831 U1(rect
[0]).x1
= 330;
12832 U2(rect
[0]).y1
= 250;
12833 U3(rect
[0]).x2
= 340;
12834 U4(rect
[0]).y2
= 260;
12835 hr
= IDirect3DViewport2_Clear(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
);
12836 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
12838 color
= get_surface_color(rt
, 328, 248);
12839 ok(compare_color(color
, 0x00ffffff, 0), "(328, 248) has color 0x%08x.\n", color
);
12840 color
= get_surface_color(rt
, 332, 248);
12841 ok(compare_color(color
, 0x00ffffff, 0), "(332, 248) has color 0x%08x.\n", color
);
12842 color
= get_surface_color(rt
, 328, 252);
12843 ok(compare_color(color
, 0x00ffffff, 0), "(328, 252) has color 0x%08x.\n", color
);
12844 color
= get_surface_color(rt
, 332, 252);
12845 ok(compare_color(color
, 0x0000ff00, 0), "(332, 252) has color 0x%08x.\n", color
);
12847 color
= get_surface_color(rt
, 338, 248);
12848 ok(compare_color(color
, 0x00ffffff, 0), "(338, 248) has color 0x%08x.\n", color
);
12849 color
= get_surface_color(rt
, 342, 248);
12850 ok(compare_color(color
, 0x00ffffff, 0), "(342, 248) has color 0x%08x.\n", color
);
12851 color
= get_surface_color(rt
, 338, 252);
12852 ok(compare_color(color
, 0x0000ff00, 0), "(338, 252) has color 0x%08x.\n", color
);
12853 color
= get_surface_color(rt
, 342, 252);
12854 ok(compare_color(color
, 0x00ffffff, 0), "(342, 252) has color 0x%08x.\n", color
);
12856 color
= get_surface_color(rt
, 328, 258);
12857 ok(compare_color(color
, 0x00ffffff, 0), "(328, 258) has color 0x%08x.\n", color
);
12858 color
= get_surface_color(rt
, 332, 258);
12859 ok(compare_color(color
, 0x0000ff00, 0), "(332, 258) has color 0x%08x.\n", color
);
12860 color
= get_surface_color(rt
, 328, 262);
12861 ok(compare_color(color
, 0x00ffffff, 0), "(328, 262) has color 0x%08x.\n", color
);
12862 color
= get_surface_color(rt
, 332, 262);
12863 ok(compare_color(color
, 0x00ffffff, 0), "(332, 262) has color 0x%08x.\n", color
);
12865 color
= get_surface_color(rt
, 338, 258);
12866 ok(compare_color(color
, 0x0000ff00, 0), "(338, 258) has color 0x%08x.\n", color
);
12867 color
= get_surface_color(rt
, 342, 258);
12868 ok(compare_color(color
, 0x00ffffff, 0), "(342, 258) has color 0x%08x.\n", color
);
12869 color
= get_surface_color(rt
, 338, 262);
12870 ok(compare_color(color
, 0x00ffffff, 0), "(338, 262) has color 0x%08x.\n", color
);
12871 color
= get_surface_color(rt
, 342, 262);
12872 ok(compare_color(color
, 0x00ffffff, 0), "(342, 262) has color 0x%08x.\n", color
);
12874 /* COLORWRITEENABLE, SRGBWRITEENABLE and scissor rectangles do not exist
12877 IDirect3DViewport2_Release(viewport3
);
12878 IDirect3DViewport2_Release(viewport2
);
12879 IDirect3DViewport2_Release(viewport
);
12880 IDirect3DMaterial2_Release(white
);
12881 IDirect3DMaterial2_Release(red
);
12882 IDirect3DMaterial2_Release(green
);
12883 IDirect3DMaterial2_Release(blue
);
12884 IDirectDrawSurface_Release(rt
);
12885 refcount
= IDirect3DDevice2_Release(device
);
12886 ok(!refcount
, "Device has %u references left.\n", refcount
);
12887 refcount
= IDirectDraw2_Release(ddraw
);
12888 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
12889 DestroyWindow(window
);
12892 struct enum_surfaces_param
12894 IDirectDrawSurface
*surfaces
[8];
12895 unsigned int count
;
12898 static HRESULT WINAPI
enum_surfaces_cb(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
12900 struct enum_surfaces_param
*param
= context
;
12901 BOOL found
= FALSE
;
12904 for (i
= 0; i
< ARRAY_SIZE(param
->surfaces
); ++i
)
12906 if (param
->surfaces
[i
] == surface
)
12913 ok(found
, "Unexpected surface %p enumerated.\n", surface
);
12914 IDirectDrawSurface_Release(surface
);
12917 return DDENUMRET_OK
;
12920 static void test_enum_surfaces(void)
12922 struct enum_surfaces_param param
= {{0}};
12923 IDirectDraw2
*ddraw
;
12924 DDSURFACEDESC desc
;
12927 ddraw
= create_ddraw();
12928 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12930 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
12931 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12933 memset(&desc
, 0, sizeof(desc
));
12934 desc
.dwSize
= sizeof(desc
);
12935 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
12936 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
12937 U2(desc
).dwMipMapCount
= 3;
12939 desc
.dwHeight
= 32;
12940 hr
= IDirectDraw2_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
12941 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
12943 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[0], &desc
.ddsCaps
, ¶m
.surfaces
[1]);
12944 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
12945 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[1], &desc
.ddsCaps
, ¶m
.surfaces
[2]);
12946 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
12947 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[2], &desc
.ddsCaps
, ¶m
.surfaces
[3]);
12948 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
12949 ok(!param
.surfaces
[3], "Got unexpected pointer %p.\n", param
.surfaces
[3]);
12951 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
12952 &desc
, ¶m
, enum_surfaces_cb
);
12953 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#x.\n", hr
);
12954 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
12957 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
12958 NULL
, ¶m
, enum_surfaces_cb
);
12959 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#x.\n", hr
);
12960 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
12962 IDirectDrawSurface_Release(param
.surfaces
[2]);
12963 IDirectDrawSurface_Release(param
.surfaces
[1]);
12964 IDirectDrawSurface_Release(param
.surfaces
[0]);
12965 IDirectDraw2_Release(ddraw
);
12968 static void test_viewport(void)
12973 RECT expected_rect
;
12974 const char *message
;
12978 {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
12979 {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
12980 {{ 0, 0, 1280, 960}, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
12981 {{ 0, 0, 2000, 1600}, { 0, 400, 639, 479}, "Viewport (0, 0) - (2000, 1600)"},
12982 {{100, 100, 640, 480}, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
12983 {{ 0, 0, 8192, 8192}, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
12985 static const struct vec2 rt_sizes
[] =
12987 {640, 480}, {1280, 960}, {320, 240}, {800, 600},
12989 static D3DMATRIX mat
=
12991 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12992 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12993 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12994 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12996 static D3DLVERTEX quad
[] =
12998 {{-1.5f
}, {-0.5f
}, {0.1f
}, 0, {0xffffffff}},
12999 {{-1.5f
}, { 0.5f
}, {0.1f
}, 0, {0xffffffff}},
13000 {{ 0.5f
}, {-0.5f
}, {0.1f
}, 0, {0xffffffff}},
13001 {{ 0.5f
}, { 0.5f
}, {0.1f
}, 0, {0xffffffff}},
13003 IDirect3DViewport2
*viewport
, *full_viewport
;
13004 IDirect3DMaterial2
*black_background
;
13005 IDirectDrawSurface
*rt
, *ds
;
13006 DDSURFACEDESC surface_desc
;
13007 IDirect3DDevice2
*device
;
13008 BOOL expected_failure
;
13009 IDirectDraw2
*ddraw
;
13010 DDPIXELFORMAT z_fmt
;
13011 D3DRECT clear_rect
;
13019 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
13020 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
13021 ddraw
= create_ddraw();
13022 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13023 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13025 skip("Failed to create a 3D device, skipping test.\n");
13026 IDirectDraw2_Release(ddraw
);
13027 DestroyWindow(window
);
13031 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
13032 ok(SUCCEEDED(hr
), "Failed to get Direct3D2 interface, hr %#x.\n", hr
);
13034 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
13035 ok(SUCCEEDED(hr
), "Failed to disable depth test, hr %#x.\n", hr
);
13036 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
13037 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
13039 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
13040 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
13041 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
13042 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
13043 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
13044 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
13046 black_background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
13048 ds
= get_depth_stencil(device
);
13049 memset(&surface_desc
, 0, sizeof(surface_desc
));
13050 surface_desc
.dwSize
= sizeof(surface_desc
);
13051 hr
= IDirectDrawSurface_GetSurfaceDesc(ds
, &surface_desc
);
13052 z_fmt
= surface_desc
.ddpfPixelFormat
;
13054 for (i
= 0; i
< ARRAY_SIZE(rt_sizes
); ++i
)
13058 memset(&surface_desc
, 0, sizeof(surface_desc
));
13059 surface_desc
.dwSize
= sizeof(surface_desc
);
13060 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
13061 surface_desc
.dwWidth
= rt_sizes
[i
].x
;
13062 surface_desc
.dwHeight
= rt_sizes
[i
].y
;
13063 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
13064 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
13065 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x (i %u).\n", hr
, i
);
13067 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
13068 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
13069 surface_desc
.ddpfPixelFormat
= z_fmt
;
13070 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
13071 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x (i %u).\n", hr
, i
);
13072 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
13073 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x (i %u).\n", hr
, i
);
13075 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
13076 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x (i %u).\n", hr
, i
);
13080 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
13081 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
13084 full_viewport
= create_viewport(device
, 0, 0, rt_sizes
[i
].x
, rt_sizes
[i
].y
);
13085 viewport_set_background(device
, full_viewport
, black_background
);
13087 U1(clear_rect
).x1
= U2(clear_rect
).y1
= 0;
13088 U3(clear_rect
).x2
= rt_sizes
[i
].x
;
13089 U4(clear_rect
).y2
= rt_sizes
[i
].y
;
13091 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
13093 expected_failure
= tests
[j
].vp
.dwX
+ tests
[j
].vp
.dwWidth
> rt_sizes
[i
].x
13094 || tests
[j
].vp
.dwY
+ tests
[j
].vp
.dwHeight
> rt_sizes
[i
].y
;
13096 hr
= IDirect3DViewport2_Clear(full_viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
13097 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x (i %u, j %u).\n", hr
, i
, j
);
13099 hr
= IDirect3D2_CreateViewport(d3d
, &viewport
, NULL
);
13100 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x (i %u, j %u).\n", hr
, i
, j
);
13101 hr
= IDirect3DViewport2_SetViewport2(viewport
, NULL
);
13102 ok(hr
== E_INVALIDARG
, "Setting NULL viewport data returned unexpected hr %#x (i %u, j %u).\n",
13104 memset(&vp
, 0, sizeof(vp
));
13105 vp
.dwSize
= sizeof(vp
);
13106 vp
.dwX
= tests
[j
].vp
.dwX
;
13107 vp
.dwY
= tests
[j
].vp
.dwY
;
13108 vp
.dwWidth
= tests
[j
].vp
.dwWidth
;
13109 vp
.dwHeight
= tests
[j
].vp
.dwHeight
;
13110 vp
.dvScaleX
= tests
[j
].vp
.dwWidth
/ 2.0f
;
13111 vp
.dvScaleY
= tests
[j
].vp
.dwHeight
/ 2.0f
;
13114 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp
);
13115 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
,
13116 "Setting viewport data returned unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
13117 hr
= IDirect3DDevice2_AddViewport(device
, viewport
);
13118 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x (i %u, j %u).\n", hr
, i
, j
);
13119 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp
);
13120 if (expected_failure
)
13121 ok(hr
== E_INVALIDARG
, "Setting viewport data returned unexpected hr %#x (i %u, j %u).\n",
13124 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x (i %u, j %u).\n", hr
, i
, j
);
13126 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
13127 ok(SUCCEEDED(hr
), "Failed to set the viewport, hr %#x (i %u, j %u).\n", hr
, i
, j
);
13128 if (expected_failure
)
13130 destroy_viewport(device
, viewport
);
13134 hr
= IDirect3DDevice2_BeginScene(device
);
13135 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x (i %u, j %u).\n", hr
, i
, j
);
13136 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
13137 ok(SUCCEEDED(hr
), "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
13138 hr
= IDirect3DDevice2_EndScene(device
);
13139 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x (i %u, j %u).\n", hr
, i
, j
);
13141 check_rect(rt
, tests
[j
].expected_rect
, tests
[j
].message
);
13143 destroy_viewport(device
, viewport
);
13146 destroy_viewport(device
, full_viewport
);
13148 hr
= IDirectDrawSurface_DeleteAttachedSurface(rt
, 0, ds
);
13149 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x (i %u).\n", hr
, i
);
13150 IDirectDrawSurface_Release(ds
);
13152 IDirectDrawSurface_Release(rt
);
13155 destroy_material(black_background
);
13156 refcount
= IDirect3DDevice2_Release(device
);
13157 ok(!refcount
, "Device has %u references left.\n", refcount
);
13158 IDirect3D2_Release(d3d
);
13159 IDirectDraw2_Release(ddraw
);
13160 DestroyWindow(window
);
13163 static void test_find_device(void)
13165 D3DFINDDEVICESEARCH search
= {0};
13166 D3DFINDDEVICERESULT result
= {0};
13167 IDirect3DDevice2
*device
;
13168 IDirectDraw2
*ddraw
;
13178 D3DDEVICEDESC_V1 hw_desc
;
13179 D3DDEVICEDESC_V1 sw_desc
;
13186 D3DDEVICEDESC_V2 hw_desc
;
13187 D3DDEVICEDESC_V2 sw_desc
;
13190 static const struct
13197 {&IID_IDirect3D
, DDERR_NOTFOUND
},
13198 {&IID_IDirect3DRampDevice
, D3D_OK
},
13199 {&IID_IDirect3DRGBDevice
, D3D_OK
},
13200 {&IID_IDirect3DMMXDevice
, D3D_OK
},
13201 {&IID_IDirect3DRefDevice
, DDERR_NOTFOUND
},
13202 {&IID_IDirect3DTnLHalDevice
, DDERR_NOTFOUND
},
13203 {&IID_IDirect3DNullDevice
, DDERR_NOTFOUND
},
13206 ddraw
= create_ddraw();
13207 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13209 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
13211 skip("D3D interface is not available, skipping test.\n");
13212 IDirectDraw2_Release(ddraw
);
13216 result
.dwSize
= sizeof(result
);
13217 search
.dwSize
= sizeof(search
);
13218 hr
= IDirect3D2_FindDevice(d3d
, NULL
, NULL
);
13219 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13220 hr
= IDirect3D2_FindDevice(d3d
, NULL
, &result
);
13221 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13222 hr
= IDirect3D2_FindDevice(d3d
, &search
, NULL
);
13223 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13224 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
13225 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13226 ok(result
.dwSize
== sizeof(result
), "Got unexpected result size %u.\n", result
.dwSize
);
13227 ok(result
.ddHwDesc
.dwSize
== sizeof(result_v2
.hw_desc
),
13228 "Got unexpected HW desc size %u.\n", result
.ddHwDesc
.dwSize
);
13229 ok(result
.ddSwDesc
.dwSize
== sizeof(result_v2
.sw_desc
),
13230 "Got unexpected SW desc size %u.\n", result
.ddSwDesc
.dwSize
);
13232 memset(&search
, 0, sizeof(search
));
13233 memset(&result
, 0, sizeof(result
));
13234 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
13235 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13237 search
.dwSize
= sizeof(search
) + 1;
13238 result
.dwSize
= sizeof(result
) + 1;
13239 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
13240 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13242 search
.dwSize
= sizeof(search
);
13244 memset(&result_v1
, 0, sizeof(result_v1
));
13245 result_v1
.size
= sizeof(result_v1
);
13246 hr
= IDirect3D2_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v1
);
13247 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13248 ok(result_v1
.hw_desc
.dwSize
== sizeof(result_v2
.hw_desc
),
13249 "Got unexpected HW desc size %u.\n", result_v1
.hw_desc
.dwSize
);
13250 ok(result_v1
.sw_desc
.dwSize
== sizeof(result_v2
.sw_desc
),
13251 "Got unexpected SW desc size %u.\n", result_v1
.sw_desc
.dwSize
);
13253 memset(&result_v2
, 0, sizeof(result_v2
));
13254 result_v2
.size
= sizeof(result_v2
);
13255 hr
= IDirect3D2_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v2
);
13256 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13257 ok(result_v2
.hw_desc
.dwSize
== sizeof(result_v2
.hw_desc
),
13258 "Got unexpected HW desc size %u.\n", result_v2
.hw_desc
.dwSize
);
13259 ok(result_v2
.sw_desc
.dwSize
== sizeof(result_v2
.sw_desc
),
13260 "Got unexpected SW desc size %u.\n", result_v2
.sw_desc
.dwSize
);
13262 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
13264 memset(&search
, 0, sizeof(search
));
13265 search
.dwSize
= sizeof(search
);
13266 search
.dwFlags
= D3DFDS_GUID
;
13267 search
.guid
= *tests
[i
].guid
;
13269 memset(&result
, 0, sizeof(result
));
13270 result
.dwSize
= sizeof(result
);
13272 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
13273 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
13274 ok(result
.dwSize
== sizeof(result
), "Test %u: Got unexpected result size %u.\n", i
, result
.dwSize
);
13277 ok(result
.ddHwDesc
.dwSize
== sizeof(result_v2
.hw_desc
),
13278 "Test %u: Got unexpected HW desc size %u.\n", i
, result
.ddHwDesc
.dwSize
);
13279 ok(result
.ddSwDesc
.dwSize
== sizeof(result_v2
.sw_desc
),
13280 "Test %u: Got unexpected SW desc size %u.\n", i
, result
.ddSwDesc
.dwSize
);
13284 ok(!result
.ddHwDesc
.dwSize
,
13285 "Test %u: Got unexpected HW desc size %u.\n", i
, result
.ddHwDesc
.dwSize
);
13286 ok(!result
.ddSwDesc
.dwSize
,
13287 "Test %u: Got unexpected SW desc size %u.\n", i
, result
.ddSwDesc
.dwSize
);
13291 /* The HAL device can only be enumerated if hardware acceleration is present. */
13292 search
.dwSize
= sizeof(search
);
13293 search
.dwFlags
= D3DFDS_GUID
;
13294 search
.guid
= IID_IDirect3DHALDevice
;
13295 result
.dwSize
= sizeof(result
);
13296 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
13298 window
= create_window();
13299 device
= create_device(ddraw
, window
, DDSCL_NORMAL
);
13301 ok(!!device
, "Failed to create a 3D device.\n");
13303 ok(!device
, "Succeeded to create a 3D device.\n");
13305 IDirect3DDevice2_Release(device
);
13306 DestroyWindow(window
);
13308 /* Curiously the colour model criteria seem to be ignored. */
13309 search
.dwSize
= sizeof(search
);
13310 search
.dwFlags
= D3DFDS_COLORMODEL
;
13311 search
.dcmColorModel
= 0xdeadbeef;
13312 result
.dwSize
= sizeof(result
);
13313 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
13314 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13316 IDirect3D2_Release(d3d
);
13317 IDirectDraw2_Release(ddraw
);
13320 static IDirectDraw2
*killfocus_ddraw
;
13321 static IDirectDrawSurface
*killfocus_surface
;
13323 static LRESULT CALLBACK
killfocus_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
13327 if (message
== WM_KILLFOCUS
)
13329 ref
= IDirectDrawSurface_Release(killfocus_surface
);
13330 ok(!ref
, "Unexpected surface refcount %u.\n", ref
);
13331 ref
= IDirectDraw2_Release(killfocus_ddraw
);
13332 ok(!ref
, "Unexpected ddraw refcount %u.\n", ref
);
13333 killfocus_ddraw
= NULL
;
13336 return DefWindowProcA(window
, message
, wparam
, lparam
);
13339 static void test_killfocus(void)
13341 DDSURFACEDESC surface_desc
;
13344 WNDCLASSA wc
= {0};
13346 wc
.lpfnWndProc
= killfocus_proc
;
13347 wc
.lpszClassName
= "ddraw_killfocus_wndproc_wc";
13348 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
13350 window
= CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW
,
13351 0, 0, 640, 480, 0, 0, 0, 0);
13353 killfocus_ddraw
= create_ddraw();
13354 ok(!!killfocus_ddraw
, "Failed to create a ddraw object.\n");
13356 hr
= IDirectDraw2_SetCooperativeLevel(killfocus_ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
13357 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13359 memset(&surface_desc
, 0, sizeof(surface_desc
));
13360 surface_desc
.dwSize
= sizeof(surface_desc
);
13361 surface_desc
.dwFlags
= DDSD_CAPS
;
13362 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
13363 hr
= IDirectDraw_CreateSurface(killfocus_ddraw
, &surface_desc
, &killfocus_surface
, NULL
);
13364 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13366 SetForegroundWindow(GetDesktopWindow());
13367 ok(!killfocus_ddraw
, "WM_KILLFOCUS was not received.\n");
13369 DestroyWindow(window
);
13370 UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL
));
13373 static void test_gdi_surface(void)
13375 IDirectDrawSurface
*primary
, *backbuffer
, *gdi_surface
;
13376 DDSCAPS caps
= {DDSCAPS_BACKBUFFER
};
13377 DDSURFACEDESC surface_desc
;
13378 IDirectDraw2
*ddraw
;
13383 window
= create_window();
13384 ddraw
= create_ddraw();
13385 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13386 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13387 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13389 /* Retrieving the GDI surface requires a primary surface to exist. */
13390 gdi_surface
= (void *)0xc0dec0de;
13391 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
13392 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
13393 ok(!gdi_surface
, "Got unexpected surface %p.\n", gdi_surface
);
13395 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
13396 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
13398 memset(&surface_desc
, 0, sizeof(surface_desc
));
13399 surface_desc
.dwSize
= sizeof(surface_desc
);
13400 surface_desc
.dwFlags
= DDSD_CAPS
;
13401 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
13402 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
13403 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13405 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
13406 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13407 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
13408 IDirectDrawSurface_Release(gdi_surface
);
13410 /* Flipping to the GDI surface requires the primary surface to be
13412 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
13413 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
13415 IDirectDrawSurface_Release(primary
);
13417 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
13418 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13420 memset(&surface_desc
, 0, sizeof(surface_desc
));
13421 surface_desc
.dwSize
= sizeof(surface_desc
);
13422 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
13423 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
13424 U5(surface_desc
).dwBackBufferCount
= 1;
13425 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
13426 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13427 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &caps
, &backbuffer
);
13428 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13429 ok(backbuffer
!= primary
, "Got unexpected backbuffer %p.\n", backbuffer
);
13431 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
13432 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13433 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
13434 IDirectDrawSurface_Release(gdi_surface
);
13436 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
13437 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13438 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
13439 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13440 ok(gdi_surface
== backbuffer
|| broken(gdi_surface
== primary
),
13441 "Got unexpected surface %p, expected %p.\n", gdi_surface
, backbuffer
);
13442 IDirectDrawSurface_Release(gdi_surface
);
13444 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
13445 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13447 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
13448 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13449 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
13450 IDirectDrawSurface_Release(gdi_surface
);
13452 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
13453 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13455 IDirectDrawSurface_Release(backbuffer
);
13456 IDirectDrawSurface_Release(primary
);
13458 refcount
= IDirectDraw2_Release(ddraw
);
13459 ok(!refcount
, "%u references left.\n", refcount
);
13460 DestroyWindow(window
);
13463 static void test_alphatest(void)
13465 #define ALPHATEST_PASSED 0x0000ff00
13466 #define ALPHATEST_FAILED 0x00ff0000
13467 D3DRECT rect_full
= {{0}, {0}, {640}, {480}};
13468 IDirect3DMaterial2
*blue
, *failed
;
13469 IDirect3DViewport2
*viewport
;
13470 IDirect3DDevice2
*device
;
13471 IDirectDrawSurface
*rt
;
13472 IDirectDraw2
*ddraw
;
13480 static const struct
13483 D3DCOLOR color_less
;
13484 D3DCOLOR color_equal
;
13485 D3DCOLOR color_greater
;
13489 {D3DCMP_NEVER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
13490 {D3DCMP_LESS
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
13491 {D3DCMP_EQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
13492 {D3DCMP_LESSEQUAL
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
13493 {D3DCMP_GREATER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
13494 {D3DCMP_NOTEQUAL
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
13495 {D3DCMP_GREATEREQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
13496 {D3DCMP_ALWAYS
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
13498 static D3DLVERTEX quad
[] =
13500 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
13501 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
13502 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
13503 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
13506 window
= create_window();
13507 ddraw
= create_ddraw();
13508 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13509 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13511 skip("Failed to create a 3D device.\n");
13512 IDirectDraw2_Release(ddraw
);
13513 DestroyWindow(window
);
13516 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
13517 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13519 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
13520 failed
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
13522 viewport
= create_viewport(device
, 0, 0, 640, 480);
13523 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
13524 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13526 viewport_set_background(device
, viewport
, blue
);
13527 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13528 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13529 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
13530 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13531 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
13532 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13533 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHATESTENABLE
, TRUE
);
13534 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13536 viewport_set_background(device
, viewport
, failed
);
13537 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
13539 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHAFUNC
, test_data
[i
].func
);
13540 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13542 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13543 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13544 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0x70);
13545 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13546 hr
= IDirect3DDevice2_BeginScene(device
);
13547 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13548 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
13549 D3DVT_LVERTEX
, quad
, ARRAY_SIZE(quad
), 0);
13550 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13551 hr
= IDirect3DDevice2_EndScene(device
);
13552 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13553 color
= get_surface_color(rt
, 320, 240);
13554 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
13555 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
13556 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
13558 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13559 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13560 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0xff70);
13561 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13562 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, &value
);
13563 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13564 ok(value
== 0xff70, "Got unexpected value %#x.\n", value
);
13565 hr
= IDirect3DDevice2_BeginScene(device
);
13566 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13567 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
13568 D3DVT_LVERTEX
, quad
, ARRAY_SIZE(quad
), 0);
13569 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13570 hr
= IDirect3DDevice2_EndScene(device
);
13571 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13572 color
= get_surface_color(rt
, 320, 240);
13573 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
13574 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
13575 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
13578 destroy_viewport(device
, viewport
);
13579 destroy_material(failed
);
13580 destroy_material(blue
);
13581 IDirectDrawSurface_Release(rt
);
13582 refcount
= IDirect3DDevice2_Release(device
);
13583 ok(!refcount
, "Device has %u references left.\n", refcount
);
13584 refcount
= IDirectDraw2_Release(ddraw
);
13585 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
13586 DestroyWindow(window
);
13589 static void test_clipper_refcount(void)
13591 IDirectDrawSurface
*surface
;
13592 IDirectDrawClipper
*clipper
, *clipper2
;
13593 DDSURFACEDESC surface_desc
;
13594 IDirectDraw2
*ddraw
;
13595 IDirectDraw
*ddraw1
;
13600 const IDirectDrawClipperVtbl
*orig_vtbl
;
13602 window
= create_window();
13603 ddraw
= create_ddraw();
13604 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13605 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13606 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13608 memset(&surface_desc
, 0, sizeof(surface_desc
));
13609 surface_desc
.dwSize
= sizeof(surface_desc
);
13610 surface_desc
.dwFlags
= DDSD_CAPS
;
13611 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
13612 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13613 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13615 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
13616 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
13617 refcount
= get_refcount((IUnknown
*)clipper
);
13618 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
13620 /* Show that clipper validation doesn't somehow happen through per-clipper vtable
13622 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper2
, NULL
);
13623 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
13624 ok(clipper
->lpVtbl
== clipper2
->lpVtbl
, "Got different clipper vtables %p and %p.\n",
13625 clipper
->lpVtbl
, clipper2
->lpVtbl
);
13626 orig_vtbl
= clipper
->lpVtbl
;
13627 IDirectDrawClipper_Release(clipper2
);
13629 /* Surfaces hold a reference to clippers. No surprises there. */
13630 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
13631 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
13632 refcount
= get_refcount((IUnknown
*)clipper
);
13633 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
13635 hr
= IDirectDrawSurface_GetClipper(surface
, &clipper2
);
13636 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#x.\n", hr
);
13637 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
13638 refcount
= IDirectDrawClipper_Release(clipper2
);
13639 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
13641 hr
= IDirectDrawSurface_SetClipper(surface
, NULL
);
13642 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
13643 refcount
= get_refcount((IUnknown
*)clipper
);
13644 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
13646 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
13647 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
13648 refcount
= get_refcount((IUnknown
*)clipper
);
13649 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
13651 refcount
= IDirectDrawSurface_Release(surface
);
13652 ok(!refcount
, "%u references left.\n", refcount
);
13653 refcount
= get_refcount((IUnknown
*)clipper
);
13654 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
13656 /* SetClipper with an invalid pointer crashes. */
13658 /* Clipper methods work with a broken vtable, with the exception of Release. */
13659 clipper
->lpVtbl
= (void *)0xdeadbeef;
13660 refcount
= orig_vtbl
->AddRef(clipper
);
13661 todo_wine
ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
13662 refcount
= orig_vtbl
->Release(clipper
);
13663 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
13665 clipper
->lpVtbl
= orig_vtbl
;
13666 refcount
= orig_vtbl
->Release(clipper
);
13667 todo_wine
ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
13669 /* Fix the refcount difference because Wine did not increase the ref in the
13670 * AddRef call above. */
13673 refcount
= IDirectDrawClipper_Release(clipper
);
13674 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
13677 /* Steal the reference and see what happens - releasing the surface works fine.
13678 * The clipper is destroyed and not kept alive by a hidden refcount - trying to
13679 * release it after the GetClipper call is likely to crash, and certain to crash
13680 * if we allocate and zero as much heap memory as we can get. */
13681 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13682 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13683 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
13684 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
13685 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
13686 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
13688 IDirectDrawClipper_Release(clipper
);
13689 IDirectDrawClipper_Release(clipper
);
13691 hr
= IDirectDrawSurface_GetClipper(surface
, &clipper2
);
13692 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#x.\n", hr
);
13693 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
13695 /* Show that invoking the Release method does not crash, but don't get the
13696 * vtable through the clipper pointer because it is no longer pointing to
13698 refcount
= orig_vtbl
->Release(clipper
);
13699 ok(!refcount
, "%u references left.\n", refcount
);
13701 refcount
= IDirectDrawSurface_Release(surface
);
13702 ok(!refcount
, "%u references left.\n", refcount
);
13704 /* It looks like the protection against invalid thispointers is part of
13705 * the IDirectDrawClipper method implementation, not IDirectDrawSurface. */
13706 clipper
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 0x1000);
13707 ok(!!clipper
, "failed to allocate memory\n");
13709 /* Assigning the vtable to our fake clipper does NOT make a difference on
13710 * native - there is a different member of the clipper implementation struct
13711 * that is used to determine if a clipper is valid. */
13712 clipper
->lpVtbl
= orig_vtbl
;
13714 refcount
= orig_vtbl
->AddRef(clipper
);
13715 todo_wine
ok(!refcount
, "Got refcount %u.\n", refcount
);
13716 refcount
= orig_vtbl
->AddRef((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef);
13717 ok(!refcount
, "Got refcount %u.\n", refcount
);
13720 hr
= orig_vtbl
->IsClipListChanged(clipper
, &changed
);
13721 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13722 todo_wine
ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
13725 hr
= orig_vtbl
->IsClipListChanged((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef, &changed
);
13726 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13727 ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
13729 /* Nope, we can't initialize our fake clipper. */
13730 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirectDraw
, (void **)&ddraw1
);
13731 ok(SUCCEEDED(hr
), "Failed to get ddraw1 interface, hr %#x.\n", hr
);
13733 hr
= orig_vtbl
->Initialize(clipper
, ddraw1
, 0);
13734 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13736 IDirectDraw_Release(ddraw1
);
13738 HeapFree(GetProcessHeap(), 0, clipper
);
13740 refcount
= IDirectDraw2_Release(ddraw
);
13741 ok(!refcount
, "%u references left.\n", refcount
);
13742 DestroyWindow(window
);
13748 DDDEVICEIDENTIFIER identifier
;
13749 DEVMODEW current_mode
;
13750 IDirectDraw2
*ddraw
;
13753 if (!(ddraw
= create_ddraw()))
13755 skip("Failed to create a ddraw object, skipping tests.\n");
13759 if (ddraw_get_identifier(ddraw
, &identifier
))
13761 trace("Driver string: \"%s\"\n", identifier
.szDriver
);
13762 trace("Description string: \"%s\"\n", identifier
.szDescription
);
13763 trace("Driver version %d.%d.%d.%d\n",
13764 HIWORD(U(identifier
.liDriverVersion
).HighPart
), LOWORD(U(identifier
.liDriverVersion
).HighPart
),
13765 HIWORD(U(identifier
.liDriverVersion
).LowPart
), LOWORD(U(identifier
.liDriverVersion
).LowPart
));
13767 IDirectDraw2_Release(ddraw
);
13769 memset(¤t_mode
, 0, sizeof(current_mode
));
13770 current_mode
.dmSize
= sizeof(current_mode
);
13771 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
13772 registry_mode
.dmSize
= sizeof(registry_mode
);
13773 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
13774 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
13775 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
13777 skip("Current mode does not match registry mode, skipping test.\n");
13781 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
13782 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
13784 test_coop_level_create_device_window();
13785 test_clipper_blt();
13786 test_coop_level_d3d_state();
13787 test_surface_interface_mismatch();
13788 test_coop_level_threaded();
13790 test_texture_load_ckey();
13791 test_viewport_object();
13799 test_window_style();
13800 test_redundant_mode_set();
13801 test_coop_level_mode_set();
13802 test_coop_level_mode_set_multi();
13804 test_coop_level_surf_create();
13805 test_coop_level_multi_window();
13806 test_clear_rect_count();
13807 test_coop_level_versions();
13808 test_lighting_interface_versions();
13809 test_coop_level_activateapp();
13810 test_unsupported_formats();
13812 test_primary_caps();
13813 test_surface_lock();
13814 test_surface_discard();
13816 test_set_surface_desc();
13817 test_user_memory_getdc();
13818 test_sysmem_overlay();
13819 test_primary_palette();
13820 test_surface_attachment();
13821 test_pixel_format();
13822 test_create_surface_pitch();
13824 test_palette_complex();
13828 test_specular_lighting();
13829 test_palette_gdi();
13830 test_palette_alpha();
13831 test_lost_device();
13832 test_surface_desc_lock();
13833 test_texturemapblend();
13834 test_viewport_clear_rect();
13836 test_colorkey_precision();
13837 test_range_colorkey();
13839 test_lockrect_invalid();
13840 test_yv12_overlay();
13841 test_offscreen_overlay();
13842 test_overlay_rect();
13844 test_blt_z_alpha();
13845 test_cross_device_blt();
13847 test_draw_primitive();
13848 test_edge_antialiasing_blending();
13849 test_transform_vertices();
13850 test_display_mode_surface_pixel_format();
13851 test_surface_desc_size();
13852 test_ck_operation();
13853 test_set_render_state();
13854 test_depth_readback();
13856 test_enum_surfaces();
13858 test_find_device();
13860 test_gdi_surface();
13862 test_clipper_refcount();