2 * Copyright 2005 Antoine Chavasse (a.chavasse@gmail.com)
3 * Copyright 2008, 2011, 2012-2013 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
22 #include "wine/test.h"
26 static BOOL is_ddraw64
= sizeof(DWORD
) != sizeof(DWORD
*);
27 static DEVMODEW registry_mode
;
29 static HRESULT (WINAPI
*pDwmIsCompositionEnabled
)(BOOL
*);
32 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
40 struct create_window_thread_param
43 HANDLE window_created
;
44 HANDLE destroy_window
;
48 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
50 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
52 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
54 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
56 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
60 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
70 if (abs(x
- y
) > ulps
)
76 static BOOL
compare_vec4(const struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
78 return compare_float(vec
->x
, x
, ulps
)
79 && compare_float(vec
->y
, y
, ulps
)
80 && compare_float(vec
->z
, z
, ulps
)
81 && compare_float(vec
->w
, w
, ulps
);
84 static BOOL
ddraw_is_warp(IDirectDraw
*ddraw
)
87 DDDEVICEIDENTIFIER identifier
;
90 if (!strcmp(winetest_platform
, "wine"))
93 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirectDraw4
, (void **)&ddraw4
);
94 ok(SUCCEEDED(hr
), "Failed to get IDirectDraw4 interface, hr %#x.\n", hr
);
95 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw4
, &identifier
, 0);
96 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#x.\n", hr
);
97 IDirectDraw4_Release(ddraw4
);
99 return !!strstr(identifier
.szDriver
, "warp");
102 static BOOL
ddraw_is_nvidia(IDirectDraw
*ddraw
)
104 IDirectDraw4
*ddraw4
;
105 DDDEVICEIDENTIFIER identifier
;
108 if (!strcmp(winetest_platform
, "wine"))
111 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirectDraw4
, (void **)&ddraw4
);
112 ok(SUCCEEDED(hr
), "Failed to get IDirectDraw4 interface, hr %#x.\n", hr
);
113 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw4
, &identifier
, 0);
114 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#x.\n", hr
);
115 IDirectDraw4_Release(ddraw4
);
117 return identifier
.dwVendorId
== 0x10de;
120 static BOOL
ddraw_is_intel(IDirectDraw
*ddraw
)
122 IDirectDraw4
*ddraw4
;
123 DDDEVICEIDENTIFIER identifier
;
126 if (!strcmp(winetest_platform
, "wine"))
129 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirectDraw4
, (void **)&ddraw4
);
130 ok(SUCCEEDED(hr
), "Failed to get IDirectDraw4 interface, hr %#x.\n", hr
);
131 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw4
, &identifier
, 0);
132 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#x.\n", hr
);
133 IDirectDraw4_Release(ddraw4
);
135 return identifier
.dwVendorId
== 0x8086;
138 static IDirectDrawSurface
*create_overlay(IDirectDraw
*ddraw
,
139 unsigned int width
, unsigned int height
, DWORD format
)
141 IDirectDrawSurface
*surface
;
144 memset(&desc
, 0, sizeof(desc
));
145 desc
.dwSize
= sizeof(desc
);
146 desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
147 desc
.dwWidth
= width
;
148 desc
.dwHeight
= height
;
149 desc
.ddsCaps
.dwCaps
= DDSCAPS_OVERLAY
;
150 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
151 desc
.ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
152 desc
.ddpfPixelFormat
.dwFourCC
= format
;
154 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &desc
, &surface
, NULL
)))
159 static DWORD WINAPI
create_window_thread_proc(void *param
)
161 struct create_window_thread_param
*p
= param
;
165 p
->window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
166 0, 0, 640, 480, 0, 0, 0, 0);
167 ret
= SetEvent(p
->window_created
);
168 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
174 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
175 DispatchMessageA(&msg
);
176 res
= WaitForSingleObject(p
->destroy_window
, 100);
177 if (res
== WAIT_OBJECT_0
)
179 if (res
!= WAIT_TIMEOUT
)
181 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
186 DestroyWindow(p
->window
);
191 static void create_window_thread(struct create_window_thread_param
*p
)
195 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
196 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
197 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
198 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
199 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
200 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
201 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
202 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
205 static void destroy_window_thread(struct create_window_thread_param
*p
)
207 SetEvent(p
->destroy_window
);
208 WaitForSingleObject(p
->thread
, INFINITE
);
209 CloseHandle(p
->destroy_window
);
210 CloseHandle(p
->window_created
);
211 CloseHandle(p
->thread
);
214 static HRESULT
set_display_mode(IDirectDraw
*ddraw
, DWORD width
, DWORD height
)
216 if (SUCCEEDED(IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 32)))
218 return IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 24);
221 static D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
223 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
224 DDSURFACEDESC surface_desc
;
228 memset(&surface_desc
, 0, sizeof(surface_desc
));
229 surface_desc
.dwSize
= sizeof(surface_desc
);
231 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
232 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
236 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
238 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
239 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
244 static void emit_process_vertices(void **ptr
, DWORD flags
, WORD base_idx
, DWORD vertex_count
)
246 D3DINSTRUCTION
*inst
= *ptr
;
247 D3DPROCESSVERTICES
*pv
= (D3DPROCESSVERTICES
*)(inst
+ 1);
249 inst
->bOpcode
= D3DOP_PROCESSVERTICES
;
250 inst
->bSize
= sizeof(*pv
);
254 pv
->wStart
= base_idx
;
256 pv
->dwCount
= vertex_count
;
262 static void emit_set_ts(void **ptr
, D3DTRANSFORMSTATETYPE state
, DWORD value
)
264 D3DINSTRUCTION
*inst
= *ptr
;
265 D3DSTATE
*ts
= (D3DSTATE
*)(inst
+ 1);
267 inst
->bOpcode
= D3DOP_STATETRANSFORM
;
268 inst
->bSize
= sizeof(*ts
);
271 U1(*ts
).dtstTransformStateType
= state
;
272 U2(*ts
).dwArg
[0] = value
;
277 static void emit_set_ls(void **ptr
, D3DLIGHTSTATETYPE state
, DWORD value
)
279 D3DINSTRUCTION
*inst
= *ptr
;
280 D3DSTATE
*ls
= (D3DSTATE
*)(inst
+ 1);
282 inst
->bOpcode
= D3DOP_STATELIGHT
;
283 inst
->bSize
= sizeof(*ls
);
286 U1(*ls
).dlstLightStateType
= state
;
287 U2(*ls
).dwArg
[0] = value
;
292 static void emit_set_rs(void **ptr
, D3DRENDERSTATETYPE state
, DWORD value
)
294 D3DINSTRUCTION
*inst
= *ptr
;
295 D3DSTATE
*rs
= (D3DSTATE
*)(inst
+ 1);
297 inst
->bOpcode
= D3DOP_STATERENDER
;
298 inst
->bSize
= sizeof(*rs
);
301 U1(*rs
).drstRenderStateType
= state
;
302 U2(*rs
).dwArg
[0] = value
;
307 static void emit_tquad(void **ptr
, WORD base_idx
)
309 D3DINSTRUCTION
*inst
= *ptr
;
310 D3DTRIANGLE
*tri
= (D3DTRIANGLE
*)(inst
+ 1);
312 inst
->bOpcode
= D3DOP_TRIANGLE
;
313 inst
->bSize
= sizeof(*tri
);
316 U1(*tri
).v1
= base_idx
;
317 U2(*tri
).v2
= base_idx
+ 1;
318 U3(*tri
).v3
= base_idx
+ 2;
319 tri
->wFlags
= D3DTRIFLAG_START
;
322 U1(*tri
).v1
= base_idx
+ 2;
323 U2(*tri
).v2
= base_idx
+ 1;
324 U3(*tri
).v3
= base_idx
+ 3;
325 tri
->wFlags
= D3DTRIFLAG_ODD
;
331 static void emit_tquad_tlist(void **ptr
, WORD base_idx
)
333 D3DINSTRUCTION
*inst
= *ptr
;
334 D3DTRIANGLE
*tri
= (D3DTRIANGLE
*)(inst
+ 1);
336 inst
->bOpcode
= D3DOP_TRIANGLE
;
337 inst
->bSize
= sizeof(*tri
);
340 U1(*tri
).v1
= base_idx
;
341 U2(*tri
).v2
= base_idx
+ 1;
342 U3(*tri
).v3
= base_idx
+ 2;
343 tri
->wFlags
= D3DTRIFLAG_START
;
346 U1(*tri
).v1
= base_idx
+ 2;
347 U2(*tri
).v2
= base_idx
+ 3;
348 U3(*tri
).v3
= base_idx
;
349 tri
->wFlags
= D3DTRIFLAG_START
;
355 static void emit_texture_load(void **ptr
, D3DTEXTUREHANDLE dst_texture
,
356 D3DTEXTUREHANDLE src_texture
)
358 D3DINSTRUCTION
*instruction
= *ptr
;
359 D3DTEXTURELOAD
*texture_load
= (D3DTEXTURELOAD
*)(instruction
+ 1);
361 instruction
->bOpcode
= D3DOP_TEXTURELOAD
;
362 instruction
->bSize
= sizeof(*texture_load
);
363 instruction
->wCount
= 1;
365 texture_load
->hDestTexture
= dst_texture
;
366 texture_load
->hSrcTexture
= src_texture
;
372 static void emit_end(void **ptr
)
374 D3DINSTRUCTION
*inst
= *ptr
;
376 inst
->bOpcode
= D3DOP_EXIT
;
383 static void set_execute_data(IDirect3DExecuteBuffer
*execute_buffer
, UINT vertex_count
, UINT offset
, UINT len
)
385 D3DEXECUTEDATA exec_data
;
388 memset(&exec_data
, 0, sizeof(exec_data
));
389 exec_data
.dwSize
= sizeof(exec_data
);
390 exec_data
.dwVertexCount
= vertex_count
;
391 exec_data
.dwInstructionOffset
= offset
;
392 exec_data
.dwInstructionLength
= len
;
393 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
394 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#x.\n", hr
);
397 static DWORD
get_device_z_depth(IDirect3DDevice
*device
)
399 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
400 IDirectDrawSurface
*ds
, *rt
;
404 if (FAILED(IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
)))
407 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ds
);
408 IDirectDrawSurface_Release(rt
);
412 desc
.dwSize
= sizeof(desc
);
413 hr
= IDirectDrawSurface_GetSurfaceDesc(ds
, &desc
);
414 IDirectDrawSurface_Release(ds
);
418 return U2(desc
).dwZBufferBitDepth
;
421 static IDirectDraw
*create_ddraw(void)
425 if (FAILED(DirectDrawCreate(NULL
, &ddraw
, NULL
)))
431 static IDirect3DDevice
*create_device(IDirectDraw
*ddraw
, HWND window
, DWORD coop_level
)
433 static const DWORD z_depths
[] = {32, 24, 16};
434 IDirectDrawSurface
*surface
, *ds
;
435 IDirect3DDevice
*device
= NULL
;
436 DDSURFACEDESC surface_desc
;
440 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, coop_level
);
441 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
443 memset(&surface_desc
, 0, sizeof(surface_desc
));
444 surface_desc
.dwSize
= sizeof(surface_desc
);
445 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
446 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
447 surface_desc
.dwWidth
= 640;
448 surface_desc
.dwHeight
= 480;
450 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
451 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
453 if (coop_level
& DDSCL_NORMAL
)
455 IDirectDrawClipper
*clipper
;
457 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
458 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
459 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
460 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
461 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
462 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
463 IDirectDrawClipper_Release(clipper
);
466 /* We used to use EnumDevices() for this, but it seems
467 * D3DDEVICEDESC.dwDeviceZBufferBitDepth only has a very casual
468 * relationship with reality. */
469 for (i
= 0; i
< sizeof(z_depths
) / sizeof(*z_depths
); ++i
)
471 memset(&surface_desc
, 0, sizeof(surface_desc
));
472 surface_desc
.dwSize
= sizeof(surface_desc
);
473 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
474 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
475 U2(surface_desc
).dwZBufferBitDepth
= z_depths
[i
];
476 surface_desc
.dwWidth
= 640;
477 surface_desc
.dwHeight
= 480;
478 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
)))
481 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
482 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
483 IDirectDrawSurface_Release(ds
);
487 if (SUCCEEDED(IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DHALDevice
, (void **)&device
)))
490 IDirectDrawSurface_DeleteAttachedSurface(surface
, 0, ds
);
493 IDirectDrawSurface_Release(surface
);
497 static IDirect3DViewport
*create_viewport(IDirect3DDevice
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
499 IDirect3DViewport
*viewport
;
504 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
505 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
506 hr
= IDirect3D_CreateViewport(d3d
, &viewport
, NULL
);
507 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
508 hr
= IDirect3DDevice_AddViewport(device
, viewport
);
509 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
510 memset(&vp
, 0, sizeof(vp
));
511 vp
.dwSize
= sizeof(vp
);
516 vp
.dvScaleX
= (float)w
/ 2.0f
;
517 vp
.dvScaleY
= (float)h
/ 2.0f
;
522 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
523 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
524 IDirect3D_Release(d3d
);
529 static void viewport_set_background(IDirect3DDevice
*device
, IDirect3DViewport
*viewport
,
530 IDirect3DMaterial
*material
)
532 D3DMATERIALHANDLE material_handle
;
535 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &material_handle
);
536 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
537 hr
= IDirect3DViewport2_SetBackground(viewport
, material_handle
);
538 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
541 static void destroy_viewport(IDirect3DDevice
*device
, IDirect3DViewport
*viewport
)
545 hr
= IDirect3DDevice_DeleteViewport(device
, viewport
);
546 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
547 IDirect3DViewport_Release(viewport
);
550 static IDirect3DMaterial
*create_material(IDirect3DDevice
*device
, D3DMATERIAL
*mat
)
552 IDirect3DMaterial
*material
;
556 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
557 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
558 hr
= IDirect3D_CreateMaterial(d3d
, &material
, NULL
);
559 ok(SUCCEEDED(hr
), "Failed to create material, hr %#x.\n", hr
);
560 hr
= IDirect3DMaterial_SetMaterial(material
, mat
);
561 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
562 IDirect3D_Release(d3d
);
567 static IDirect3DMaterial
*create_diffuse_material(IDirect3DDevice
*device
, float r
, float g
, float b
, float a
)
571 memset(&mat
, 0, sizeof(mat
));
572 mat
.dwSize
= sizeof(mat
);
573 U1(U(mat
).diffuse
).r
= r
;
574 U2(U(mat
).diffuse
).g
= g
;
575 U3(U(mat
).diffuse
).b
= b
;
576 U4(U(mat
).diffuse
).a
= a
;
578 return create_material(device
, &mat
);
581 static IDirect3DMaterial
*create_emissive_material(IDirect3DDevice
*device
, float r
, float g
, float b
, float a
)
585 memset(&mat
, 0, sizeof(mat
));
586 mat
.dwSize
= sizeof(mat
);
587 U1(U3(mat
).emissive
).r
= r
;
588 U2(U3(mat
).emissive
).g
= g
;
589 U3(U3(mat
).emissive
).b
= b
;
590 U4(U3(mat
).emissive
).a
= a
;
592 return create_material(device
, &mat
);
595 static void destroy_material(IDirect3DMaterial
*material
)
597 IDirect3DMaterial_Release(material
);
604 WPARAM expect_wparam
;
607 static const struct message
*expect_messages
;
609 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
611 if (expect_messages
&& message
== expect_messages
->message
)
613 if (expect_messages
->check_wparam
)
614 ok (wparam
== expect_messages
->expect_wparam
,
615 "Got unexpected wparam %lx for message %x, expected %lx.\n",
616 wparam
, message
, expect_messages
->expect_wparam
);
621 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
624 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
625 * interface. This prevents subsequent SetCooperativeLevel() calls on a
626 * different window from failing with DDERR_HWNDALREADYSET. */
627 static void fix_wndproc(HWND window
, LONG_PTR proc
)
632 if (!(ddraw
= create_ddraw()))
635 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
636 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
637 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
638 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
639 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
641 IDirectDraw_Release(ddraw
);
644 static HRESULT CALLBACK
restore_callback(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
646 HRESULT hr
= IDirectDrawSurface_Restore(surface
);
647 ok(SUCCEEDED(hr
) || hr
== DDERR_IMPLICITLYCREATED
, "Failed to restore surface, hr %#x.\n", hr
);
648 IDirectDrawSurface_Release(surface
);
653 static HRESULT
restore_surfaces(IDirectDraw
*ddraw
)
655 return IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
,
656 NULL
, NULL
, restore_callback
);
659 static void test_coop_level_create_device_window(void)
661 HWND focus_window
, device_window
;
665 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
666 0, 0, 640, 480, 0, 0, 0, 0);
667 ddraw
= create_ddraw();
668 ok(!!ddraw
, "Failed to create a ddraw object.\n");
670 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
671 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
672 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
673 ok(!device_window
, "Unexpected device window found.\n");
674 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
675 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
676 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
677 ok(!device_window
, "Unexpected device window found.\n");
678 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
679 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
680 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
681 ok(!device_window
, "Unexpected device window found.\n");
682 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
683 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
684 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
685 ok(!device_window
, "Unexpected device window found.\n");
686 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
687 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
688 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
689 ok(!device_window
, "Unexpected device window found.\n");
691 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
692 if (broken(hr
== DDERR_INVALIDPARAMS
))
694 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
695 IDirectDraw_Release(ddraw
);
696 DestroyWindow(focus_window
);
700 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
701 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
702 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
703 ok(!device_window
, "Unexpected device window found.\n");
704 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
705 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
706 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
707 ok(!device_window
, "Unexpected device window found.\n");
709 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
710 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
711 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
712 ok(!device_window
, "Unexpected device window found.\n");
713 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
714 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
715 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
716 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
717 ok(!!device_window
, "Device window not found.\n");
719 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
720 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
721 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
722 ok(!device_window
, "Unexpected device window found.\n");
723 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
724 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
725 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
726 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
727 ok(!!device_window
, "Device window not found.\n");
729 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
730 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
731 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
732 ok(!device_window
, "Unexpected device window found.\n");
733 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
734 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
735 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
736 ok(!device_window
, "Unexpected device window found.\n");
737 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
738 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
739 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
740 ok(!device_window
, "Unexpected device window found.\n");
741 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
742 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
743 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
744 ok(!!device_window
, "Device window not found.\n");
746 IDirectDraw_Release(ddraw
);
747 DestroyWindow(focus_window
);
750 static void test_clipper_blt(void)
752 IDirectDrawSurface
*src_surface
, *dst_surface
;
753 RECT client_rect
, src_rect
;
754 IDirectDrawClipper
*clipper
;
755 DDSURFACEDESC surface_desc
;
756 unsigned int i
, j
, x
, y
;
768 static const DWORD src_data
[] =
770 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
771 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
772 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
774 static const D3DCOLOR expected1
[] =
776 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
777 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
778 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
779 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
781 /* Nvidia on Windows seems to have an off-by-one error
782 * when processing source rectangles. Our left = 1 and
783 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
784 * read as well, but only for the edge pixels on the
785 * output image. The bug happens on the y axis as well,
786 * but we only read one row there, and all source rows
787 * contain the same data. This bug is not dependent on
788 * the presence of a clipper. */
789 static const D3DCOLOR expected1_broken
[] =
791 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
792 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
793 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
794 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
796 static const D3DCOLOR expected2
[] =
798 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
799 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
800 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
801 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
804 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
805 10, 10, 640, 480, 0, 0, 0, 0);
806 ShowWindow(window
, SW_SHOW
);
807 ddraw
= create_ddraw();
808 ok(!!ddraw
, "Failed to create a ddraw object.\n");
810 ret
= GetClientRect(window
, &client_rect
);
811 ok(ret
, "Failed to get client rect.\n");
812 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
813 ok(ret
, "Failed to map client rect.\n");
815 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
816 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
818 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
819 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
820 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
821 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
822 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
823 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
824 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
825 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
826 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
827 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
828 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
829 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
830 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
831 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
832 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
833 "Got unexpected bounding rect %s, expected %s.\n",
834 wine_dbgstr_rect(&rgn_data
->rdh
.rcBound
), wine_dbgstr_rect(&client_rect
));
835 HeapFree(GetProcessHeap(), 0, rgn_data
);
837 r1
= CreateRectRgn(0, 0, 320, 240);
838 ok(!!r1
, "Failed to create region.\n");
839 r2
= CreateRectRgn(320, 240, 640, 480);
840 ok(!!r2
, "Failed to create region.\n");
841 CombineRgn(r1
, r1
, r2
, RGN_OR
);
842 ret
= GetRegionData(r1
, 0, NULL
);
843 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
844 ret
= GetRegionData(r1
, ret
, rgn_data
);
845 ok(!!ret
, "Failed to get region data.\n");
850 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
851 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
852 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
853 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
854 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
855 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
857 HeapFree(GetProcessHeap(), 0, rgn_data
);
859 memset(&surface_desc
, 0, sizeof(surface_desc
));
860 surface_desc
.dwSize
= sizeof(surface_desc
);
861 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
862 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
863 surface_desc
.dwWidth
= 640;
864 surface_desc
.dwHeight
= 480;
865 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
866 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
867 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
868 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
869 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
870 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
872 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
873 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
874 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
875 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
877 memset(&fx
, 0, sizeof(fx
));
878 fx
.dwSize
= sizeof(fx
);
879 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
880 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
881 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
882 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
884 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
885 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
886 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
887 ptr
= surface_desc
.lpSurface
;
888 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
889 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
890 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
891 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
892 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
894 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
895 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
897 SetRect(&src_rect
, 1, 1, 5, 2);
898 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
899 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
900 for (i
= 0; i
< 4; ++i
)
902 for (j
= 0; j
< 4; ++j
)
904 x
= 80 * ((2 * j
) + 1);
905 y
= 60 * ((2 * i
) + 1);
906 color
= get_surface_color(dst_surface
, x
, y
);
907 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
908 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
909 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
913 U5(fx
).dwFillColor
= 0xff0000ff;
914 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
915 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
916 for (i
= 0; i
< 4; ++i
)
918 for (j
= 0; j
< 4; ++j
)
920 x
= 80 * ((2 * j
) + 1);
921 y
= 60 * ((2 * i
) + 1);
922 color
= get_surface_color(dst_surface
, x
, y
);
923 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
924 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
928 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
929 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#x.\n", hr
);
931 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
932 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
933 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
934 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
935 DestroyWindow(window
);
936 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
937 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
938 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
939 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
940 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
941 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
942 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
943 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
944 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
945 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
946 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
947 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
949 IDirectDrawSurface_Release(dst_surface
);
950 IDirectDrawSurface_Release(src_surface
);
951 refcount
= IDirectDrawClipper_Release(clipper
);
952 ok(!refcount
, "Clipper has %u references left.\n", refcount
);
953 IDirectDraw_Release(ddraw
);
956 static void test_coop_level_d3d_state(void)
958 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
959 IDirectDrawSurface
*rt
, *surface
;
960 IDirect3DMaterial
*background
;
961 IDirect3DViewport
*viewport
;
962 IDirect3DDevice
*device
;
963 D3DMATERIAL material
;
969 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
970 0, 0, 640, 480, 0, 0, 0, 0);
971 ddraw
= create_ddraw();
972 ok(!!ddraw
, "Failed to create a ddraw object.\n");
973 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
975 skip("Failed to create a 3D device, skipping test.\n");
976 IDirectDraw_Release(ddraw
);
977 DestroyWindow(window
);
981 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
982 viewport
= create_viewport(device
, 0, 0, 640, 480);
983 viewport_set_background(device
, viewport
, background
);
985 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
986 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
987 hr
= IDirect3DViewport_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
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
992 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
993 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
994 hr
= IDirectDrawSurface_IsLost(rt
);
995 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
996 hr
= restore_surfaces(ddraw
);
997 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
999 memset(&material
, 0, sizeof(material
));
1000 material
.dwSize
= sizeof(material
);
1001 U1(U(material
).diffuse
).r
= 0.0f
;
1002 U2(U(material
).diffuse
).g
= 1.0f
;
1003 U3(U(material
).diffuse
).b
= 0.0f
;
1004 U4(U(material
).diffuse
).a
= 1.0f
;
1005 hr
= IDirect3DMaterial_SetMaterial(background
, &material
);
1006 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
1008 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&surface
);
1009 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1010 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
1011 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1012 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1013 color
= get_surface_color(rt
, 320, 240);
1014 ok(compare_color(color
, 0x0000ff00, 1) || broken(compare_color(color
, 0x00000000, 1)),
1015 "Got unexpected color 0x%08x.\n", color
);
1017 destroy_viewport(device
, viewport
);
1018 destroy_material(background
);
1019 IDirectDrawSurface_Release(surface
);
1020 IDirectDrawSurface_Release(rt
);
1021 IDirect3DDevice_Release(device
);
1022 IDirectDraw_Release(ddraw
);
1023 DestroyWindow(window
);
1026 static void test_surface_interface_mismatch(void)
1028 IDirectDraw
*ddraw
= NULL
;
1029 IDirectDrawSurface
*surface
= NULL
, *ds
;
1030 IDirectDrawSurface3
*surface3
= NULL
;
1031 IDirect3DDevice
*device
= NULL
;
1032 IDirect3DViewport
*viewport
= NULL
;
1033 IDirect3DMaterial
*background
= NULL
;
1034 DDSURFACEDESC surface_desc
;
1040 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1042 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1043 0, 0, 640, 480, 0, 0, 0, 0);
1044 ddraw
= create_ddraw();
1045 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1046 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1048 skip("Failed to create a 3D device, skipping test.\n");
1049 IDirectDraw_Release(ddraw
);
1050 DestroyWindow(window
);
1053 z_depth
= get_device_z_depth(device
);
1054 ok(!!z_depth
, "Failed to get device z depth.\n");
1055 IDirect3DDevice_Release(device
);
1058 memset(&surface_desc
, 0, sizeof(surface_desc
));
1059 surface_desc
.dwSize
= sizeof(surface_desc
);
1060 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1061 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
1062 surface_desc
.dwWidth
= 640;
1063 surface_desc
.dwHeight
= 480;
1065 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1066 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1068 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
1071 skip("Failed to get the IDirectDrawSurface3 interface, skipping test.\n");
1075 memset(&surface_desc
, 0, sizeof(surface_desc
));
1076 surface_desc
.dwSize
= sizeof(surface_desc
);
1077 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
1078 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1079 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
1080 surface_desc
.dwWidth
= 640;
1081 surface_desc
.dwHeight
= 480;
1082 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
1083 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
1087 /* Using a different surface interface version still works */
1088 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
1089 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
1090 refcount
= IDirectDrawSurface_Release(ds
);
1091 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
1096 hr
= IDirectDrawSurface3_QueryInterface(surface3
, &IID_IDirect3DHALDevice
, (void **)&device
);
1097 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
1101 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1102 viewport
= create_viewport(device
, 0, 0, 640, 480);
1103 viewport_set_background(device
, viewport
, background
);
1105 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1106 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1107 color
= get_surface_color(surface
, 320, 240);
1108 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1112 destroy_viewport(device
, viewport
);
1114 destroy_material(background
);
1115 if (surface3
) IDirectDrawSurface3_Release(surface3
);
1116 if (surface
) IDirectDrawSurface_Release(surface
);
1117 if (device
) IDirect3DDevice_Release(device
);
1118 if (ddraw
) IDirectDraw_Release(ddraw
);
1119 DestroyWindow(window
);
1122 static void test_coop_level_threaded(void)
1124 struct create_window_thread_param p
;
1128 ddraw
= create_ddraw();
1129 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1130 create_window_thread(&p
);
1132 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1133 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1135 IDirectDraw_Release(ddraw
);
1136 destroy_window_thread(&p
);
1139 static ULONG
get_refcount(IUnknown
*test_iface
)
1141 IUnknown_AddRef(test_iface
);
1142 return IUnknown_Release(test_iface
);
1145 static void test_viewport(void)
1151 IDirect3DViewport
*viewport
, *another_vp
;
1152 IDirect3DViewport2
*viewport2
;
1153 IDirect3DViewport3
*viewport3
;
1154 IDirectDrawGammaControl
*gamma
;
1156 IDirect3DDevice
*device
;
1159 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1160 0, 0, 640, 480, 0, 0, 0, 0);
1161 ddraw
= create_ddraw();
1162 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1163 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1165 skip("Failed to create a 3D device, skipping test.\n");
1166 IDirectDraw_Release(ddraw
);
1167 DestroyWindow(window
);
1171 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
1172 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1173 ref
= get_refcount((IUnknown
*) d3d
);
1174 ok(ref
== 2, "IDirect3D refcount is %d\n", ref
);
1176 hr
= IDirect3D_CreateViewport(d3d
, &viewport
, NULL
);
1177 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1178 ref
= get_refcount((IUnknown
*)viewport
);
1179 ok(ref
== 1, "Initial IDirect3DViewport refcount is %u\n", ref
);
1180 ref
= get_refcount((IUnknown
*)d3d
);
1181 ok(ref
== 2, "IDirect3D refcount is %u\n", ref
);
1183 /* E_FAIL return values are returned by Winetestbot Windows NT machines. While not supporting
1184 * newer interfaces is legitimate for old ddraw versions, E_FAIL violates Microsoft's rules
1185 * for QueryInterface, hence the broken() */
1186 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1187 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1188 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_FAIL
), "Got unexpected hr %#x.\n", hr
);
1189 ok(gamma
== NULL
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1190 if (SUCCEEDED(hr
)) IDirectDrawGammaControl_Release(gamma
);
1191 /* NULL iid: Segfaults */
1193 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirect3DViewport2
, (void **)&viewport2
);
1194 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
|| broken(hr
== E_FAIL
),
1195 "Failed to QI IDirect3DViewport2, hr %#x.\n", hr
);
1198 ref
= get_refcount((IUnknown
*)viewport
);
1199 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
1200 ref
= get_refcount((IUnknown
*)viewport2
);
1201 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
1202 IDirect3DViewport2_Release(viewport2
);
1206 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirect3DViewport3
, (void **)&viewport3
);
1207 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
|| broken(hr
== E_FAIL
),
1208 "Failed to QI IDirect3DViewport3, hr %#x.\n", hr
);
1211 ref
= get_refcount((IUnknown
*)viewport
);
1212 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
1213 ref
= get_refcount((IUnknown
*)viewport3
);
1214 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1215 IDirect3DViewport3_Release(viewport3
);
1218 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IUnknown
, (void **)&unknown
);
1219 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#x.\n", hr
);
1222 ref
= get_refcount((IUnknown
*)viewport
);
1223 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
1224 ref
= get_refcount(unknown
);
1225 ok(ref
== 2, "IUnknown refcount is %u\n", ref
);
1226 IUnknown_Release(unknown
);
1229 /* AddViewport(NULL): Segfault */
1230 hr
= IDirect3DDevice_DeleteViewport(device
, NULL
);
1231 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1233 hr
= IDirect3D_CreateViewport(d3d
, &another_vp
, NULL
);
1234 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1236 hr
= IDirect3DDevice_AddViewport(device
, viewport
);
1237 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1238 ref
= get_refcount((IUnknown
*) viewport
);
1239 ok(ref
== 2, "IDirect3DViewport refcount is %d\n", ref
);
1240 hr
= IDirect3DDevice_AddViewport(device
, another_vp
);
1241 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1242 ref
= get_refcount((IUnknown
*) another_vp
);
1243 ok(ref
== 2, "IDirect3DViewport refcount is %d\n", ref
);
1245 hr
= IDirect3DDevice_DeleteViewport(device
, another_vp
);
1246 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#x.\n", hr
);
1247 ref
= get_refcount((IUnknown
*) another_vp
);
1248 ok(ref
== 1, "IDirect3DViewport refcount is %d\n", ref
);
1250 IDirect3DDevice_Release(device
);
1251 ref
= get_refcount((IUnknown
*) viewport
);
1252 ok(ref
== 1, "IDirect3DViewport refcount is %d\n", ref
);
1254 IDirect3DViewport_Release(another_vp
);
1255 IDirect3D_Release(d3d
);
1256 IDirect3DViewport_Release(viewport
);
1257 DestroyWindow(window
);
1258 IDirectDraw_Release(ddraw
);
1261 static void test_zenable(void)
1263 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1264 static D3DTLVERTEX tquad
[] =
1266 {{ 0.0f
}, {480.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1267 {{ 0.0f
}, { 0.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1268 {{640.0f
}, {480.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1269 {{640.0f
}, { 0.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1271 IDirect3DExecuteBuffer
*execute_buffer
;
1272 D3DEXECUTEBUFFERDESC exec_desc
;
1273 IDirect3DMaterial
*background
;
1274 IDirect3DViewport
*viewport
;
1275 IDirect3DDevice
*device
;
1276 IDirectDrawSurface
*rt
;
1286 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1287 0, 0, 640, 480, 0, 0, 0, 0);
1288 ddraw
= create_ddraw();
1289 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1290 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1292 skip("Failed to create a 3D device, skipping test.\n");
1293 IDirectDraw_Release(ddraw
);
1294 DestroyWindow(window
);
1298 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1299 viewport
= create_viewport(device
, 0, 0, 640, 480);
1300 viewport_set_background(device
, viewport
, background
);
1302 memset(&exec_desc
, 0, sizeof(exec_desc
));
1303 exec_desc
.dwSize
= sizeof(exec_desc
);
1304 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
1305 exec_desc
.dwBufferSize
= 1024;
1306 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
1308 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
1309 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
1310 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
1311 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
1312 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
1313 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(tquad
);
1314 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
1315 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1316 emit_tquad(&ptr
, 0);
1318 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
1319 inst_length
-= sizeof(tquad
);
1320 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
1321 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
1323 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1324 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1325 hr
= IDirect3DDevice_BeginScene(device
);
1326 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1327 set_execute_data(execute_buffer
, 4, sizeof(tquad
), inst_length
);
1328 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1329 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1330 hr
= IDirect3DDevice_EndScene(device
);
1331 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1333 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1334 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1335 for (i
= 0; i
< 4; ++i
)
1337 for (j
= 0; j
< 4; ++j
)
1339 x
= 80 * ((2 * j
) + 1);
1340 y
= 60 * ((2 * i
) + 1);
1341 color
= get_surface_color(rt
, x
, y
);
1342 ok(compare_color(color
, 0x0000ff00, 1),
1343 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1346 IDirectDrawSurface_Release(rt
);
1348 destroy_viewport(device
, viewport
);
1349 IDirect3DExecuteBuffer_Release(execute_buffer
);
1350 destroy_material(background
);
1351 IDirect3DDevice_Release(device
);
1352 IDirectDraw_Release(ddraw
);
1353 DestroyWindow(window
);
1356 static void test_ck_rgba(void)
1358 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1359 static D3DTLVERTEX tquad
[] =
1361 {{ 0.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1362 {{ 0.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1363 {{640.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1364 {{640.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1365 {{ 0.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1366 {{ 0.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1367 {{640.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1368 {{640.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1370 /* Supposedly there was no D3DRENDERSTATE_COLORKEYENABLE in D3D < 5.
1371 * Maybe the WARP driver on Windows 8 ignores setting it via the older
1372 * device interface but it's buggy in that the internal state is not
1373 * initialized, or possibly toggling D3DRENDERSTATE_COLORKEYENABLE /
1374 * D3DRENDERSTATE_ALPHABLENDENABLE has unintended side effects.
1375 * Checking the W8 test results it seems like test 1 fails most of the time
1376 * and test 0 fails very rarely. */
1379 D3DCOLOR fill_color
;
1382 D3DCOLOR result1
, result1_r200
, result1_warp
;
1383 D3DCOLOR result2
, result2_r200
, result2_warp
;
1387 /* r200 on Windows doesn't check the alpha component when applying the color
1388 * key, so the key matches on every texel. */
1389 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000, 0x0000ff00,
1390 0x000000ff, 0x000000ff, 0x0000ff00},
1391 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000, 0x0000ff00,
1392 0x000000ff, 0x000000ff, 0x0000ff00},
1393 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1394 0x0000ff00, 0x0000ff00, 0x0000ff00},
1395 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1396 0x0000ff00, 0x0000ff00, 0x0000ff00},
1397 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00ff0000, 0x00807f00,
1398 0x00807f00, 0x000000ff, 0x00807f00},
1399 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000, 0x0000ff00,
1400 0x0000ff00, 0x000000ff, 0x0000ff00},
1401 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00, 0x00807f00,
1402 0x00807f00, 0x00807f00, 0x00807f00},
1403 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1404 0x0000ff00, 0x0000ff00, 0x0000ff00},
1407 IDirect3DExecuteBuffer
*execute_buffer
;
1408 D3DTEXTUREHANDLE texture_handle
;
1409 D3DEXECUTEBUFFERDESC exec_desc
;
1410 IDirect3DMaterial
*background
;
1411 IDirectDrawSurface
*surface
;
1412 IDirect3DViewport
*viewport
;
1413 DDSURFACEDESC surface_desc
;
1414 IDirect3DTexture
*texture
;
1415 IDirect3DDevice
*device
;
1416 IDirectDrawSurface
*rt
;
1424 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1425 0, 0, 640, 480, 0, 0, 0, 0);
1426 ddraw
= create_ddraw();
1427 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1428 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1430 skip("Failed to create a 3D device, skipping test.\n");
1431 IDirectDraw_Release(ddraw
);
1432 DestroyWindow(window
);
1436 background
= create_diffuse_material(device
, 1.0, 0.0f
, 0.0f
, 1.0f
);
1437 viewport
= create_viewport(device
, 0, 0, 640, 480);
1438 viewport_set_background(device
, viewport
, background
);
1440 memset(&surface_desc
, 0, sizeof(surface_desc
));
1441 surface_desc
.dwSize
= sizeof(surface_desc
);
1442 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1443 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1444 surface_desc
.dwWidth
= 256;
1445 surface_desc
.dwHeight
= 256;
1446 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1447 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1448 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1449 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1450 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1451 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1452 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1453 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1454 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1455 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1456 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1457 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
1458 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1459 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
1460 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1461 IDirect3DTexture_Release(texture
);
1463 memset(&exec_desc
, 0, sizeof(exec_desc
));
1464 exec_desc
.dwSize
= sizeof(exec_desc
);
1465 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
1466 exec_desc
.dwBufferSize
= 1024;
1467 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
1468 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
1469 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
1471 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1472 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1474 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
1476 UINT draw1_len
, draw2_len
;
1479 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
1480 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
1481 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
1482 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(tquad
);
1483 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
1484 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1485 emit_set_rs(&ptr
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1486 emit_set_rs(&ptr
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1487 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1488 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1489 emit_tquad(&ptr
, 0);
1491 draw1_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- sizeof(tquad
);
1492 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 4, 4);
1493 emit_tquad(&ptr
, 0);
1494 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1496 draw2_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw1_len
;
1497 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
1498 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
1500 memset(&fx
, 0, sizeof(fx
));
1501 fx
.dwSize
= sizeof(fx
);
1502 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1503 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1504 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1506 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
1507 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1508 hr
= IDirect3DDevice_BeginScene(device
);
1509 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1510 set_execute_data(execute_buffer
, 8, sizeof(tquad
), draw1_len
);
1511 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1512 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1513 hr
= IDirect3DDevice_EndScene(device
);
1514 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1516 color
= get_surface_color(rt
, 320, 240);
1517 ok(compare_color(color
, tests
[i
].result1
, 1)
1518 || broken(compare_color(color
, tests
[i
].result1_r200
, 1))
1519 || broken(compare_color(color
, tests
[i
].result1_warp
, 1)),
1520 "Got unexpected color 0x%08x for test %u.\n", color
, i
);
1522 U5(fx
).dwFillColor
= 0xff0000ff;
1523 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1524 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1526 hr
= IDirect3DDevice_BeginScene(device
);
1527 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1528 set_execute_data(execute_buffer
, 8, sizeof(tquad
) + draw1_len
, draw2_len
);
1529 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1530 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1531 hr
= IDirect3DDevice_EndScene(device
);
1532 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1534 /* This tests that fragments that are masked out by the color key are
1535 * discarded, instead of just fully transparent. */
1536 color
= get_surface_color(rt
, 320, 240);
1537 ok(compare_color(color
, tests
[i
].result2
, 1)
1538 || broken(compare_color(color
, tests
[i
].result2_r200
, 1))
1539 || broken(compare_color(color
, tests
[i
].result2_warp
, 1)),
1540 "Got unexpected color 0x%08x for test %u.\n", color
, i
);
1543 IDirectDrawSurface_Release(rt
);
1544 IDirect3DExecuteBuffer_Release(execute_buffer
);
1545 IDirectDrawSurface_Release(surface
);
1546 destroy_viewport(device
, viewport
);
1547 destroy_material(background
);
1548 IDirect3DDevice_Release(device
);
1549 IDirectDraw_Release(ddraw
);
1550 DestroyWindow(window
);
1553 static void test_ck_default(void)
1555 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1556 static D3DTLVERTEX tquad
[] =
1558 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1559 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1560 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1561 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1563 IDirect3DExecuteBuffer
*execute_buffer
;
1564 IDirectDrawSurface
*surface
, *rt
;
1565 D3DTEXTUREHANDLE texture_handle
;
1566 D3DEXECUTEBUFFERDESC exec_desc
;
1567 IDirect3DMaterial
*background
;
1568 UINT draw1_offset
, draw1_len
;
1569 UINT draw2_offset
, draw2_len
;
1570 UINT draw3_offset
, draw3_len
;
1571 UINT draw4_offset
, draw4_len
;
1572 IDirect3DViewport
*viewport
;
1573 DDSURFACEDESC surface_desc
;
1574 IDirect3DTexture
*texture
;
1575 IDirect3DDevice
*device
;
1583 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1584 0, 0, 640, 480, 0, 0, 0, 0);
1585 ddraw
= create_ddraw();
1586 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1587 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1589 skip("Failed to create a 3D device, skipping test.\n");
1590 IDirectDraw_Release(ddraw
);
1591 DestroyWindow(window
);
1595 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1596 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1598 background
= create_diffuse_material(device
, 0.0, 1.0f
, 0.0f
, 1.0f
);
1599 viewport
= create_viewport(device
, 0, 0, 640, 480);
1600 viewport_set_background(device
, viewport
, background
);
1602 memset(&surface_desc
, 0, sizeof(surface_desc
));
1603 surface_desc
.dwSize
= sizeof(surface_desc
);
1604 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1605 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1606 surface_desc
.dwWidth
= 256;
1607 surface_desc
.dwHeight
= 256;
1608 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1609 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1610 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1611 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1612 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1613 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1614 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
1615 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
1616 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1617 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1618 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
1619 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1620 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
1621 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1622 IDirect3DTexture_Release(texture
);
1624 memset(&fx
, 0, sizeof(fx
));
1625 fx
.dwSize
= sizeof(fx
);
1626 U5(fx
).dwFillColor
= 0x000000ff;
1627 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1628 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
1630 memset(&exec_desc
, 0, sizeof(exec_desc
));
1631 exec_desc
.dwSize
= sizeof(exec_desc
);
1632 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
1633 exec_desc
.dwBufferSize
= 1024;
1634 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
1635 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
1636 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
1638 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
1639 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
1640 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
1641 ptr
= (BYTE
*)exec_desc
.lpData
+ sizeof(tquad
);
1642 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
1643 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1644 emit_tquad(&ptr
, 0);
1646 draw1_offset
= sizeof(tquad
);
1647 draw1_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw1_offset
;
1648 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
1649 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, FALSE
);
1650 emit_tquad(&ptr
, 0);
1652 draw2_offset
= draw1_offset
+ draw1_len
;
1653 draw2_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw2_offset
;
1654 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
1655 emit_tquad(&ptr
, 0);
1657 draw3_offset
= draw2_offset
+ draw2_len
;
1658 draw3_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw3_offset
;
1659 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
1660 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
1661 emit_tquad(&ptr
, 0);
1662 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1664 draw4_offset
= draw3_offset
+ draw3_len
;
1665 draw4_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw4_offset
;
1666 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
1667 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
1669 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1670 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1671 hr
= IDirect3DDevice_BeginScene(device
);
1672 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1673 set_execute_data(execute_buffer
, 4, draw1_offset
, draw1_len
);
1674 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1675 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1676 hr
= IDirect3DDevice_EndScene(device
);
1677 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1678 color
= get_surface_color(rt
, 320, 240);
1679 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1681 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1682 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1683 hr
= IDirect3DDevice_BeginScene(device
);
1684 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1685 set_execute_data(execute_buffer
, 4, draw2_offset
, draw2_len
);
1686 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1687 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1688 hr
= IDirect3DDevice_EndScene(device
);
1689 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1690 color
= get_surface_color(rt
, 320, 240);
1691 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1693 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1694 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1695 hr
= IDirect3DDevice_BeginScene(device
);
1696 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1697 set_execute_data(execute_buffer
, 4, draw3_offset
, draw3_len
);
1698 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1699 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1700 hr
= IDirect3DDevice_EndScene(device
);
1701 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1702 color
= get_surface_color(rt
, 320, 240);
1703 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1705 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1706 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1707 hr
= IDirect3DDevice_BeginScene(device
);
1708 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1709 set_execute_data(execute_buffer
, 4, draw4_offset
, draw4_len
);
1710 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1711 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1712 hr
= IDirect3DDevice_EndScene(device
);
1713 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1714 color
= get_surface_color(rt
, 320, 240);
1715 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1717 IDirect3DExecuteBuffer_Release(execute_buffer
);
1718 IDirectDrawSurface_Release(surface
);
1719 destroy_viewport(device
, viewport
);
1720 destroy_material(background
);
1721 IDirectDrawSurface_Release(rt
);
1722 IDirect3DDevice_Release(device
);
1723 IDirectDraw_Release(ddraw
);
1724 DestroyWindow(window
);
1727 static void test_ck_complex(void)
1729 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
1730 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
1731 DDSURFACEDESC surface_desc
;
1732 IDirect3DDevice
*device
;
1733 DDCOLORKEY color_key
;
1740 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1741 0, 0, 640, 480, 0, 0, 0, 0);
1742 ddraw
= create_ddraw();
1743 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1744 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
1746 skip("Failed to create a 3D device, skipping test.\n");
1747 DestroyWindow(window
);
1748 IDirectDraw2_Release(ddraw
);
1751 IDirect3DDevice_Release(device
);
1753 memset(&surface_desc
, 0, sizeof(surface_desc
));
1754 surface_desc
.dwSize
= sizeof(surface_desc
);
1755 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1756 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
1757 surface_desc
.dwWidth
= 128;
1758 surface_desc
.dwHeight
= 128;
1759 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1760 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1762 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1763 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1764 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1765 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1766 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1767 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1768 memset(&color_key
, 0, sizeof(color_key
));
1769 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1770 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1771 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1772 color_key
.dwColorSpaceLowValue
);
1773 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1774 color_key
.dwColorSpaceHighValue
);
1777 IDirectDrawSurface_AddRef(mipmap
);
1778 for (i
= 0; i
< 7; ++i
)
1780 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
1781 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
1783 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1784 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
1785 color_key
.dwColorSpaceLowValue
= 0x000000ff;
1786 color_key
.dwColorSpaceHighValue
= 0x000000ff;
1787 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1788 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x, i %u.\n", hr
, i
);
1789 memset(&color_key
, 0, sizeof(color_key
));
1790 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1791 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x, i %u.\n", hr
, i
);
1792 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
1793 color_key
.dwColorSpaceLowValue
, i
);
1794 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
1795 color_key
.dwColorSpaceHighValue
, i
);
1797 IDirectDrawSurface_Release(mipmap
);
1801 memset(&color_key
, 0, sizeof(color_key
));
1802 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1803 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1804 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1805 color_key
.dwColorSpaceLowValue
);
1806 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1807 color_key
.dwColorSpaceHighValue
);
1809 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
1810 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
1811 IDirectDrawSurface_Release(mipmap
);
1812 refcount
= IDirectDrawSurface_Release(surface
);
1813 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1815 memset(&surface_desc
, 0, sizeof(surface_desc
));
1816 surface_desc
.dwSize
= sizeof(surface_desc
);
1817 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
1818 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
1819 surface_desc
.dwBackBufferCount
= 1;
1820 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1821 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1823 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1824 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1825 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1826 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1827 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1828 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1829 memset(&color_key
, 0, sizeof(color_key
));
1830 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
1831 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1832 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1833 color_key
.dwColorSpaceLowValue
);
1834 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1835 color_key
.dwColorSpaceHighValue
);
1837 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
1838 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
1840 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1841 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
1842 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
1843 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
1844 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1845 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1846 memset(&color_key
, 0, sizeof(color_key
));
1847 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
1848 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
1849 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1850 color_key
.dwColorSpaceLowValue
);
1851 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
1852 color_key
.dwColorSpaceHighValue
);
1854 IDirectDrawSurface_Release(tmp
);
1856 refcount
= IDirectDrawSurface_Release(surface
);
1857 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1858 refcount
= IDirectDraw_Release(ddraw
);
1859 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
1860 DestroyWindow(window
);
1866 REFIID refcount_iid
;
1870 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
1871 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
1873 ULONG refcount
, expected_refcount
;
1874 IUnknown
*iface1
, *iface2
;
1878 for (i
= 0; i
< entry_count
; ++i
)
1880 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
1881 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
1884 for (j
= 0; j
< entry_count
; ++j
)
1886 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
1887 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
1890 expected_refcount
= 0;
1891 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
1892 ++expected_refcount
;
1893 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
1894 ++expected_refcount
;
1895 refcount
= IUnknown_Release(iface2
);
1896 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
1897 refcount
, test_name
, i
, j
, expected_refcount
);
1901 expected_refcount
= 0;
1902 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
1903 ++expected_refcount
;
1904 refcount
= IUnknown_Release(iface1
);
1905 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
1906 refcount
, test_name
, i
, expected_refcount
);
1911 static void test_surface_qi(void)
1913 static const struct qi_test tests
[] =
1915 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
1916 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
1917 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
1918 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1919 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
1920 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
1921 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
1922 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
1923 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
1924 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
1925 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
1926 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
1927 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
1928 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
1929 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
1930 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
1931 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
1932 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
1933 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
1934 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
1935 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
1936 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
1937 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
1938 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
1939 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
1940 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
1941 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
1942 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
1943 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
1944 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
1945 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
1946 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
1947 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
1948 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
1949 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
1952 IDirectDrawSurface
*surface
;
1953 DDSURFACEDESC surface_desc
;
1954 IDirect3DDevice
*device
;
1959 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
1961 win_skip("DirectDrawCreateEx not available, skipping test.\n");
1965 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1966 0, 0, 640, 480, 0, 0, 0, 0);
1967 ddraw
= create_ddraw();
1968 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1969 /* Try to create a D3D device to see if the ddraw implementation supports
1970 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
1971 * doesn't support e.g. the IDirect3DTexture interfaces. */
1972 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1974 skip("Failed to create a 3D device, skipping test.\n");
1975 IDirectDraw_Release(ddraw
);
1976 DestroyWindow(window
);
1979 IDirect3DDevice_Release(device
);
1981 memset(&surface_desc
, 0, sizeof(surface_desc
));
1982 surface_desc
.dwSize
= sizeof(surface_desc
);
1983 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1984 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1985 surface_desc
.dwWidth
= 512;
1986 surface_desc
.dwHeight
= 512;
1987 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, (IDirectDrawSurface
**)0xdeadbeef, NULL
);
1988 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
1989 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1990 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1992 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface
, tests
, sizeof(tests
) / sizeof(*tests
));
1994 IDirectDrawSurface_Release(surface
);
1995 IDirectDraw_Release(ddraw
);
1996 DestroyWindow(window
);
1999 static void test_device_qi(void)
2001 static const struct qi_test tests
[] =
2003 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
2004 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
2005 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2006 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2007 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2008 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2009 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2010 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2011 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2012 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2013 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2014 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2015 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2016 {&IID_IDirect3DHALDevice
, &IID_IDirectDrawSurface
, S_OK
},
2017 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2018 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2019 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2020 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2021 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2022 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2023 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2024 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2025 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2026 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2027 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2028 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2029 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2030 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2031 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2032 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2033 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2034 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2035 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2036 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2037 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2038 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2042 IDirect3DDevice
*device
;
2046 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2048 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2052 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2053 0, 0, 640, 480, 0, 0, 0, 0);
2054 ddraw
= create_ddraw();
2055 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2056 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2058 skip("Failed to create a 3D device, skipping test.\n");
2059 IDirectDraw_Release(ddraw
);
2060 DestroyWindow(window
);
2064 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirectDrawSurface
, tests
, sizeof(tests
) / sizeof(*tests
));
2066 IDirect3DDevice_Release(device
);
2067 IDirectDraw_Release(ddraw
);
2068 DestroyWindow(window
);
2071 static void test_wndproc(void)
2073 LONG_PTR proc
, ddraw_proc
;
2080 static struct message messages
[] =
2082 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2083 {WM_MOVE
, FALSE
, 0},
2084 {WM_SIZE
, FALSE
, 0},
2085 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2086 {WM_ACTIVATE
, FALSE
, 0},
2087 {WM_SETFOCUS
, FALSE
, 0},
2091 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2092 ddraw
= create_ddraw();
2093 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2095 wc
.lpfnWndProc
= test_proc
;
2096 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2097 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2099 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2100 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2102 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2103 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2104 (LONG_PTR
)test_proc
, proc
);
2105 expect_messages
= messages
;
2106 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2107 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2108 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2109 expect_messages
= NULL
;
2110 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2111 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2112 (LONG_PTR
)test_proc
, proc
);
2113 ref
= IDirectDraw_Release(ddraw
);
2114 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2115 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2116 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2117 (LONG_PTR
)test_proc
, proc
);
2119 /* DDSCL_NORMAL doesn't. */
2120 ddraw
= create_ddraw();
2121 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2122 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2123 (LONG_PTR
)test_proc
, proc
);
2124 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2125 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2126 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2127 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2128 (LONG_PTR
)test_proc
, proc
);
2129 ref
= IDirectDraw_Release(ddraw
);
2130 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2131 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2132 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2133 (LONG_PTR
)test_proc
, proc
);
2135 /* The original window proc is only restored by ddraw if the current
2136 * window proc matches the one ddraw set. This also affects switching
2137 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2138 ddraw
= create_ddraw();
2139 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2140 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2141 (LONG_PTR
)test_proc
, proc
);
2142 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2143 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2144 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2145 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2146 (LONG_PTR
)test_proc
, proc
);
2148 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2149 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2150 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2151 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2152 (LONG_PTR
)test_proc
, proc
);
2153 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2154 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2155 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2156 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2157 (LONG_PTR
)test_proc
, proc
);
2158 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2159 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2160 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2161 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2162 (LONG_PTR
)DefWindowProcA
, proc
);
2163 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2164 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2165 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)ddraw_proc
);
2166 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2167 (LONG_PTR
)DefWindowProcA
, proc
);
2168 ref
= IDirectDraw_Release(ddraw
);
2169 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2170 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2171 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2172 (LONG_PTR
)test_proc
, proc
);
2174 ddraw
= create_ddraw();
2175 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2176 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2177 (LONG_PTR
)test_proc
, proc
);
2178 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2179 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2180 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2181 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2182 (LONG_PTR
)test_proc
, proc
);
2183 ref
= IDirectDraw_Release(ddraw
);
2184 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2185 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2186 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2187 (LONG_PTR
)DefWindowProcA
, proc
);
2189 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2190 expect_messages
= NULL
;
2191 DestroyWindow(window
);
2192 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2195 static void test_window_style(void)
2197 LONG style
, exstyle
, tmp
, expected_style
;
2198 RECT fullscreen_rect
, r
;
2205 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2206 0, 0, 100, 100, 0, 0, 0, 0);
2207 ddraw
= create_ddraw();
2208 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2210 style
= GetWindowLongA(window
, GWL_STYLE
);
2211 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2212 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2214 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2215 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2217 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2218 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2219 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2220 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2222 GetWindowRect(window
, &r
);
2223 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2224 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2225 GetClientRect(window
, &r
);
2226 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2228 ret
= SetForegroundWindow(GetDesktopWindow());
2229 ok(ret
, "Failed to set foreground window.\n");
2231 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2232 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2233 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2234 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2236 ret
= SetForegroundWindow(window
);
2237 ok(ret
, "Failed to set foreground window.\n");
2238 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2239 * the next tests expect this. */
2240 ShowWindow(window
, SW_HIDE
);
2242 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2243 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2245 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2246 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2247 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2248 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2250 ShowWindow(window
, SW_SHOW
);
2251 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2252 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2254 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2255 expected_style
= style
| WS_VISIBLE
;
2256 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2257 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2258 expected_style
= exstyle
| WS_EX_TOPMOST
;
2259 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2261 ret
= SetForegroundWindow(GetDesktopWindow());
2262 ok(ret
, "Failed to set foreground window.\n");
2263 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2264 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
2265 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2266 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2267 expected_style
= exstyle
| WS_EX_TOPMOST
;
2268 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2270 ref
= IDirectDraw_Release(ddraw
);
2271 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2273 DestroyWindow(window
);
2276 static void test_redundant_mode_set(void)
2278 DDSURFACEDESC surface_desc
= {0};
2285 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2286 0, 0, 100, 100, 0, 0, 0, 0);
2287 ddraw
= create_ddraw();
2288 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2290 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2291 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2293 surface_desc
.dwSize
= sizeof(surface_desc
);
2294 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
2295 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
2297 hr
= IDirectDraw_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2298 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
2299 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2301 GetWindowRect(window
, &r
);
2304 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2305 GetWindowRect(window
, &s
);
2306 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2308 hr
= IDirectDraw_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2309 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
2310 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2312 GetWindowRect(window
, &s
);
2313 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2315 ref
= IDirectDraw_Release(ddraw
);
2316 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2318 DestroyWindow(window
);
2321 static SIZE screen_size
;
2323 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2325 if (message
== WM_SIZE
)
2327 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2328 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2331 return test_proc(hwnd
, message
, wparam
, lparam
);
2334 struct test_coop_level_mode_set_enum_param
2336 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
2339 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC
*surface_desc
, void *context
)
2341 struct test_coop_level_mode_set_enum_param
*param
= context
;
2343 if (U1(surface_desc
->ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
2344 return DDENUMRET_OK
;
2345 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
2346 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
2347 return DDENUMRET_OK
;
2349 if (!param
->ddraw_width
)
2351 param
->ddraw_width
= surface_desc
->dwWidth
;
2352 param
->ddraw_height
= surface_desc
->dwHeight
;
2353 return DDENUMRET_OK
;
2355 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
2356 return DDENUMRET_OK
;
2358 param
->user32_width
= surface_desc
->dwWidth
;
2359 param
->user32_height
= surface_desc
->dwHeight
;
2360 return DDENUMRET_CANCEL
;
2363 static void test_coop_level_mode_set(void)
2365 IDirectDrawSurface
*primary
;
2366 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
2374 struct test_coop_level_mode_set_enum_param param
;
2379 static const struct message exclusive_messages
[] =
2381 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2382 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2383 {WM_SIZE
, FALSE
, 0},
2384 {WM_DISPLAYCHANGE
, FALSE
, 0},
2387 static const struct message exclusive_focus_loss_messages
[] =
2389 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
},
2390 {WM_DISPLAYCHANGE
, FALSE
, 0},
2391 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2392 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
2393 * SW_MINIMIZED, causing a recursive window activation that does not
2394 * produce the same result in Wine yet. Ignore the difference for now.
2395 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
2396 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2397 {WM_MOVE
, FALSE
, 0},
2398 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2399 {WM_ACTIVATEAPP
, TRUE
, FALSE
},
2402 static const struct message exclusive_focus_restore_messages
[] =
2404 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
2405 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
2406 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
2407 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
2408 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
2409 /* Native redundantly sets the window size here. */
2410 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
2411 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
2412 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
2413 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
2416 static const struct message sc_restore_messages
[] =
2418 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
2419 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2420 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2421 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
2424 static const struct message sc_minimize_messages
[] =
2426 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
2427 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2428 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2429 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2432 static const struct message sc_maximize_messages
[] =
2434 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
2435 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2436 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2437 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
2441 static const struct message normal_messages
[] =
2443 {WM_DISPLAYCHANGE
, FALSE
, 0},
2447 ddraw
= create_ddraw();
2448 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2450 memset(¶m
, 0, sizeof(param
));
2451 hr
= IDirectDraw_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
2452 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#x.\n", hr
);
2453 ref
= IDirectDraw_Release(ddraw
);
2454 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2456 if (!param
.user32_height
)
2458 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
2462 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2463 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
2464 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
2466 memset(&devmode
, 0, sizeof(devmode
));
2467 devmode
.dmSize
= sizeof(devmode
);
2468 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2469 devmode
.dmPelsWidth
= param
.user32_width
;
2470 devmode
.dmPelsHeight
= param
.user32_height
;
2471 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2472 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2474 ddraw
= create_ddraw();
2475 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2477 wc
.lpfnWndProc
= mode_set_proc
;
2478 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2479 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2481 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2482 0, 0, 100, 100, 0, 0, 0, 0);
2484 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2485 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2487 GetWindowRect(window
, &r
);
2488 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2489 wine_dbgstr_rect(&r
));
2491 memset(&ddsd
, 0, sizeof(ddsd
));
2492 ddsd
.dwSize
= sizeof(ddsd
);
2493 ddsd
.dwFlags
= DDSD_CAPS
;
2494 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2496 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2497 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2498 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2499 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2500 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2501 param
.user32_width
, ddsd
.dwWidth
);
2502 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2503 param
.user32_height
, ddsd
.dwHeight
);
2505 GetWindowRect(window
, &r
);
2506 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2507 wine_dbgstr_rect(&r
));
2509 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2510 expect_messages
= exclusive_messages
;
2514 hr
= IDirectDrawSurface_IsLost(primary
);
2515 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2516 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
2517 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2518 hr
= IDirectDrawSurface_IsLost(primary
);
2519 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2521 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2522 expect_messages
= NULL
;
2523 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
2524 "Expected screen size %ux%u, got %ux%u.\n",
2525 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
2527 GetWindowRect(window
, &r
);
2528 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2529 wine_dbgstr_rect(&r
));
2531 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2532 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2533 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2534 param
.user32_width
, ddsd
.dwWidth
);
2535 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2536 param
.user32_height
, ddsd
.dwHeight
);
2537 IDirectDrawSurface_Release(primary
);
2539 memset(&ddsd
, 0, sizeof(ddsd
));
2540 ddsd
.dwSize
= sizeof(ddsd
);
2541 ddsd
.dwFlags
= DDSD_CAPS
;
2542 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2544 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2545 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2546 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2547 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2548 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2549 param
.ddraw_width
, ddsd
.dwWidth
);
2550 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2551 param
.ddraw_height
, ddsd
.dwHeight
);
2553 GetWindowRect(window
, &r
);
2554 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2555 wine_dbgstr_rect(&r
));
2557 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2558 expect_messages
= exclusive_messages
;
2562 hr
= IDirectDrawSurface_IsLost(primary
);
2563 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2564 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2565 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2566 hr
= IDirectDrawSurface_IsLost(primary
);
2567 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2569 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2570 expect_messages
= NULL
;
2571 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
2572 "Expected screen size %ux%u, got %ux%u.\n",
2573 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
2575 GetWindowRect(window
, &r
);
2576 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2577 wine_dbgstr_rect(&r
));
2579 expect_messages
= exclusive_focus_loss_messages
;
2580 ret
= SetForegroundWindow(GetDesktopWindow());
2581 ok(ret
, "Failed to set foreground window.\n");
2582 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2583 memset(&devmode
, 0, sizeof(devmode
));
2584 devmode
.dmSize
= sizeof(devmode
);
2585 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2586 ok(ret
, "Failed to get display mode.\n");
2587 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
2588 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpect screen size %ux%u.\n",
2589 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2591 expect_messages
= exclusive_focus_restore_messages
;
2592 ShowWindow(window
, SW_RESTORE
);
2593 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2595 GetWindowRect(window
, &r
);
2596 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2597 wine_dbgstr_rect(&r
));
2598 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2599 ok(ret
, "Failed to get display mode.\n");
2600 ok(devmode
.dmPelsWidth
== param
.ddraw_width
2601 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpect screen size %ux%u.\n",
2602 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2604 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2605 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2606 /* Normally the primary should be restored here. Unfortunately this causes the
2607 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
2608 * testbot. Another Restore call would presumably avoid the crash, but it also moots
2609 * the point of the GetSurfaceDesc call. */
2611 expect_messages
= sc_minimize_messages
;
2612 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
2613 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2614 expect_messages
= NULL
;
2616 expect_messages
= sc_restore_messages
;
2617 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
2618 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2619 expect_messages
= NULL
;
2621 expect_messages
= sc_maximize_messages
;
2622 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
2623 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2624 expect_messages
= NULL
;
2626 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2627 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2629 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2630 expect_messages
= exclusive_messages
;
2634 hr
= IDirectDrawSurface_IsLost(primary
);
2635 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2636 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2637 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2638 hr
= IDirectDrawSurface_IsLost(primary
);
2639 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2641 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2642 expect_messages
= NULL
;
2643 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
2644 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
2645 "Expected screen size %ux%u, got %ux%u.\n",
2646 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
2648 GetWindowRect(window
, &r
);
2649 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2650 wine_dbgstr_rect(&r
));
2652 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2653 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2654 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2655 param
.ddraw_width
, ddsd
.dwWidth
);
2656 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2657 param
.ddraw_height
, ddsd
.dwHeight
);
2658 IDirectDrawSurface_Release(primary
);
2661 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
2662 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2664 memset(&ddsd
, 0, sizeof(ddsd
));
2665 ddsd
.dwSize
= sizeof(ddsd
);
2666 ddsd
.dwFlags
= DDSD_CAPS
;
2667 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2669 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2670 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2671 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2672 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2673 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2674 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2675 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2676 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2678 GetWindowRect(window
, &r
);
2679 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2680 wine_dbgstr_rect(&r
));
2682 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2683 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2685 GetWindowRect(window
, &r
);
2686 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2687 wine_dbgstr_rect(&r
));
2689 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2690 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2691 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2692 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2693 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2694 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2695 IDirectDrawSurface_Release(primary
);
2697 memset(&ddsd
, 0, sizeof(ddsd
));
2698 ddsd
.dwSize
= sizeof(ddsd
);
2699 ddsd
.dwFlags
= DDSD_CAPS
;
2700 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2702 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2703 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2704 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2705 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2706 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2707 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2708 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2709 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2711 GetWindowRect(window
, &r
);
2712 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2713 wine_dbgstr_rect(&r
));
2715 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2716 expect_messages
= normal_messages
;
2720 hr
= IDirectDrawSurface_IsLost(primary
);
2721 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2722 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2723 devmode
.dmPelsWidth
= param
.user32_width
;
2724 devmode
.dmPelsHeight
= param
.user32_height
;
2725 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2726 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2727 hr
= IDirectDrawSurface_IsLost(primary
);
2728 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2730 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2731 expect_messages
= NULL
;
2732 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2734 GetWindowRect(window
, &r
);
2735 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2736 wine_dbgstr_rect(&r
));
2738 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2739 expect_messages
= normal_messages
;
2743 hr
= IDirectDrawSurface_Restore(primary
);
2744 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
2745 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
2746 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
2748 win_skip("Broken SetDisplayMode(), skipping remaining tests.\n");
2749 IDirectDrawSurface_Release(primary
);
2750 IDirectDraw_Release(ddraw
);
2753 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2754 hr
= IDirectDrawSurface_Restore(primary
);
2755 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
2756 hr
= IDirectDrawSurface_IsLost(primary
);
2757 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2759 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2760 expect_messages
= NULL
;
2761 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2763 GetWindowRect(window
, &r
);
2764 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2765 wine_dbgstr_rect(&r
));
2767 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2768 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2769 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2770 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2771 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2772 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2773 IDirectDrawSurface_Release(primary
);
2775 memset(&ddsd
, 0, sizeof(ddsd
));
2776 ddsd
.dwSize
= sizeof(ddsd
);
2777 ddsd
.dwFlags
= DDSD_CAPS
;
2778 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2780 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2781 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2782 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2783 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2784 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2785 param
.ddraw_width
, ddsd
.dwWidth
);
2786 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2787 param
.ddraw_height
, ddsd
.dwHeight
);
2789 GetWindowRect(window
, &r
);
2790 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2791 wine_dbgstr_rect(&r
));
2793 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2794 expect_messages
= normal_messages
;
2798 hr
= IDirectDrawSurface_IsLost(primary
);
2799 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2800 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2801 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2802 hr
= IDirectDrawSurface_IsLost(primary
);
2803 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2805 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2806 expect_messages
= NULL
;
2807 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2809 GetWindowRect(window
, &r
);
2810 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2811 wine_dbgstr_rect(&r
));
2813 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2814 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2815 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2816 param
.ddraw_width
, ddsd
.dwWidth
);
2817 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2818 param
.ddraw_height
, ddsd
.dwHeight
);
2819 IDirectDrawSurface_Release(primary
);
2821 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2822 ok(ret
, "Failed to get display mode.\n");
2823 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
2824 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
2825 "Expected resolution %ux%u, got %ux%u.\n",
2826 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
2827 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2828 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
2829 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2831 memset(&ddsd
, 0, sizeof(ddsd
));
2832 ddsd
.dwSize
= sizeof(ddsd
);
2833 ddsd
.dwFlags
= DDSD_CAPS
;
2834 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2836 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2837 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2838 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2839 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2840 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2841 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2842 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2843 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2845 GetWindowRect(window
, &r
);
2846 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2847 wine_dbgstr_rect(&r
));
2849 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
2850 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
2851 * not DDSCL_FULLSCREEN. */
2852 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2853 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2855 GetWindowRect(window
, &r
);
2856 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2857 wine_dbgstr_rect(&r
));
2859 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2860 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2861 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2862 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2863 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2864 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2865 IDirectDrawSurface_Release(primary
);
2867 memset(&ddsd
, 0, sizeof(ddsd
));
2868 ddsd
.dwSize
= sizeof(ddsd
);
2869 ddsd
.dwFlags
= DDSD_CAPS
;
2870 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2872 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2873 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2874 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2875 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2876 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2877 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2878 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2879 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2881 GetWindowRect(window
, &r
);
2882 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2883 wine_dbgstr_rect(&r
));
2885 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2886 expect_messages
= normal_messages
;
2890 hr
= IDirectDrawSurface_IsLost(primary
);
2891 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2892 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2893 devmode
.dmPelsWidth
= param
.user32_width
;
2894 devmode
.dmPelsHeight
= param
.user32_height
;
2895 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2896 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2897 hr
= IDirectDrawSurface_IsLost(primary
);
2898 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2900 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2901 expect_messages
= NULL
;
2902 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2904 GetWindowRect(window
, &r
);
2905 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2906 wine_dbgstr_rect(&r
));
2908 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2909 expect_messages
= normal_messages
;
2913 hr
= IDirectDrawSurface_Restore(primary
);
2914 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
2915 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
2916 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2917 hr
= IDirectDrawSurface_Restore(primary
);
2918 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
2919 hr
= IDirectDrawSurface_IsLost(primary
);
2920 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2922 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2923 expect_messages
= NULL
;
2924 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2926 GetWindowRect(window
, &r
);
2927 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2928 wine_dbgstr_rect(&r
));
2930 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2931 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2932 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2933 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2934 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2935 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2936 IDirectDrawSurface_Release(primary
);
2938 memset(&ddsd
, 0, sizeof(ddsd
));
2939 ddsd
.dwSize
= sizeof(ddsd
);
2940 ddsd
.dwFlags
= DDSD_CAPS
;
2941 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2943 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2944 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2945 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2946 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2947 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2948 param
.ddraw_width
, ddsd
.dwWidth
);
2949 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2950 param
.ddraw_height
, ddsd
.dwHeight
);
2952 GetWindowRect(window
, &r
);
2953 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2954 wine_dbgstr_rect(&r
));
2956 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2957 expect_messages
= normal_messages
;
2961 hr
= IDirectDrawSurface_IsLost(primary
);
2962 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2963 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2964 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2965 hr
= IDirectDrawSurface_IsLost(primary
);
2966 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2968 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2969 expect_messages
= NULL
;
2970 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2972 GetWindowRect(window
, &r
);
2973 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2974 wine_dbgstr_rect(&r
));
2976 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2977 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2978 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2979 param
.ddraw_width
, ddsd
.dwWidth
);
2980 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2981 param
.ddraw_height
, ddsd
.dwHeight
);
2982 IDirectDrawSurface_Release(primary
);
2984 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2985 ok(ret
, "Failed to get display mode.\n");
2986 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
2987 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
2988 "Expected resolution %ux%u, got %ux%u.\n",
2989 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
2990 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2991 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
2992 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2994 memset(&ddsd
, 0, sizeof(ddsd
));
2995 ddsd
.dwSize
= sizeof(ddsd
);
2996 ddsd
.dwFlags
= DDSD_CAPS
;
2997 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2999 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3000 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3001 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3002 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3003 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3004 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3005 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3006 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3007 IDirectDrawSurface_Release(primary
);
3009 GetWindowRect(window
, &r
);
3010 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3011 wine_dbgstr_rect(&r
));
3013 /* Unlike ddraw2-7, changing from EXCLUSIVE to NORMAL does not restore the resolution */
3014 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3015 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3016 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3017 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3019 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3020 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3022 memset(&ddsd
, 0, sizeof(ddsd
));
3023 ddsd
.dwSize
= sizeof(ddsd
);
3024 ddsd
.dwFlags
= DDSD_CAPS
;
3025 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3027 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3028 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3029 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3030 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3031 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3032 param
.ddraw_width
, ddsd
.dwWidth
);
3033 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3034 param
.ddraw_height
, ddsd
.dwHeight
);
3035 IDirectDrawSurface_Release(primary
);
3036 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
3037 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3039 ref
= IDirectDraw_Release(ddraw
);
3040 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3042 GetWindowRect(window
, &r
);
3043 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3044 wine_dbgstr_rect(&r
));
3047 expect_messages
= NULL
;
3048 DestroyWindow(window
);
3049 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3052 static void test_coop_level_mode_set_multi(void)
3054 IDirectDraw
*ddraw1
, *ddraw2
;
3060 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3061 0, 0, 100, 100, 0, 0, 0, 0);
3062 ddraw1
= create_ddraw();
3063 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3065 /* With just a single ddraw object, the display mode is restored on
3067 hr
= set_display_mode(ddraw1
, 800, 600);
3068 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3070 win_skip("Broken SetDisplayMode(), skipping test.\n");
3071 IDirectDraw_Release(ddraw1
);
3072 DestroyWindow(window
);
3075 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3076 w
= GetSystemMetrics(SM_CXSCREEN
);
3077 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3078 h
= GetSystemMetrics(SM_CYSCREEN
);
3079 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3081 ref
= IDirectDraw_Release(ddraw1
);
3082 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3083 w
= GetSystemMetrics(SM_CXSCREEN
);
3084 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3085 h
= GetSystemMetrics(SM_CYSCREEN
);
3086 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3088 /* When there are multiple ddraw objects, the display mode is restored to
3089 * the initial mode, before the first SetDisplayMode() call. */
3090 ddraw1
= create_ddraw();
3091 hr
= set_display_mode(ddraw1
, 800, 600);
3092 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3093 w
= GetSystemMetrics(SM_CXSCREEN
);
3094 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3095 h
= GetSystemMetrics(SM_CYSCREEN
);
3096 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3098 ddraw2
= create_ddraw();
3099 hr
= set_display_mode(ddraw2
, 640, 480);
3100 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3101 w
= GetSystemMetrics(SM_CXSCREEN
);
3102 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3103 h
= GetSystemMetrics(SM_CYSCREEN
);
3104 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3106 ref
= IDirectDraw_Release(ddraw2
);
3107 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3108 w
= GetSystemMetrics(SM_CXSCREEN
);
3109 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3110 h
= GetSystemMetrics(SM_CYSCREEN
);
3111 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3113 ref
= IDirectDraw_Release(ddraw1
);
3114 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3115 w
= GetSystemMetrics(SM_CXSCREEN
);
3116 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3117 h
= GetSystemMetrics(SM_CYSCREEN
);
3118 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3120 /* Regardless of release ordering. */
3121 ddraw1
= create_ddraw();
3122 hr
= set_display_mode(ddraw1
, 800, 600);
3123 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3124 w
= GetSystemMetrics(SM_CXSCREEN
);
3125 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3126 h
= GetSystemMetrics(SM_CYSCREEN
);
3127 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3129 ddraw2
= create_ddraw();
3130 hr
= set_display_mode(ddraw2
, 640, 480);
3131 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3132 w
= GetSystemMetrics(SM_CXSCREEN
);
3133 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3134 h
= GetSystemMetrics(SM_CYSCREEN
);
3135 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3137 ref
= IDirectDraw_Release(ddraw1
);
3138 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3139 w
= GetSystemMetrics(SM_CXSCREEN
);
3140 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3141 h
= GetSystemMetrics(SM_CYSCREEN
);
3142 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3144 ref
= IDirectDraw_Release(ddraw2
);
3145 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3146 w
= GetSystemMetrics(SM_CXSCREEN
);
3147 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3148 h
= GetSystemMetrics(SM_CYSCREEN
);
3149 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3151 /* But only for ddraw objects that called SetDisplayMode(). */
3152 ddraw1
= create_ddraw();
3153 ddraw2
= create_ddraw();
3154 hr
= set_display_mode(ddraw2
, 640, 480);
3155 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3156 w
= GetSystemMetrics(SM_CXSCREEN
);
3157 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3158 h
= GetSystemMetrics(SM_CYSCREEN
);
3159 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3161 ref
= IDirectDraw_Release(ddraw1
);
3162 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3163 w
= GetSystemMetrics(SM_CXSCREEN
);
3164 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3165 h
= GetSystemMetrics(SM_CYSCREEN
);
3166 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3168 ref
= IDirectDraw_Release(ddraw2
);
3169 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3170 w
= GetSystemMetrics(SM_CXSCREEN
);
3171 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3172 h
= GetSystemMetrics(SM_CYSCREEN
);
3173 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3175 /* If there's a ddraw object that's currently in exclusive mode, it blocks
3176 * restoring the display mode. */
3177 ddraw1
= create_ddraw();
3178 hr
= set_display_mode(ddraw1
, 800, 600);
3179 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3180 w
= GetSystemMetrics(SM_CXSCREEN
);
3181 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3182 h
= GetSystemMetrics(SM_CYSCREEN
);
3183 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3185 ddraw2
= create_ddraw();
3186 hr
= set_display_mode(ddraw2
, 640, 480);
3187 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3188 w
= GetSystemMetrics(SM_CXSCREEN
);
3189 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3190 h
= GetSystemMetrics(SM_CYSCREEN
);
3191 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3193 hr
= IDirectDraw_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3194 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3196 ref
= IDirectDraw_Release(ddraw1
);
3197 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3198 w
= GetSystemMetrics(SM_CXSCREEN
);
3199 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3200 h
= GetSystemMetrics(SM_CYSCREEN
);
3201 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3203 ref
= IDirectDraw_Release(ddraw2
);
3204 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3205 w
= GetSystemMetrics(SM_CXSCREEN
);
3206 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3207 h
= GetSystemMetrics(SM_CYSCREEN
);
3208 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3210 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
3211 ddraw1
= create_ddraw();
3212 hr
= set_display_mode(ddraw1
, 800, 600);
3213 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3214 w
= GetSystemMetrics(SM_CXSCREEN
);
3215 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3216 h
= GetSystemMetrics(SM_CYSCREEN
);
3217 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3219 hr
= IDirectDraw_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3220 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3222 ddraw2
= create_ddraw();
3223 hr
= set_display_mode(ddraw2
, 640, 480);
3224 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
3226 ref
= IDirectDraw_Release(ddraw1
);
3227 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3228 w
= GetSystemMetrics(SM_CXSCREEN
);
3229 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3230 h
= GetSystemMetrics(SM_CYSCREEN
);
3231 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3233 ref
= IDirectDraw_Release(ddraw2
);
3234 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3235 w
= GetSystemMetrics(SM_CXSCREEN
);
3236 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3237 h
= GetSystemMetrics(SM_CYSCREEN
);
3238 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3240 DestroyWindow(window
);
3243 static void test_initialize(void)
3249 ddraw
= create_ddraw();
3250 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3252 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
3253 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
3254 IDirectDraw_Release(ddraw
);
3257 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw
, (void **)&ddraw
);
3258 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw instance, hr %#x.\n", hr
);
3259 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
3262 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
3263 hr
= IDirect3D_Initialize(d3d
, NULL
);
3264 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
3265 IDirect3D_Release(d3d
);
3268 skip("D3D interface is not available, skipping test.\n");
3269 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
3270 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
3271 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
3272 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
3273 IDirectDraw_Release(ddraw
);
3276 if (0) /* This crashes on the W2KPROSP4 testbot. */
3279 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirect3D
, (void **)&d3d
);
3280 ok(hr
== E_NOINTERFACE
, "CoCreateInstance returned hr %#x, expected E_NOINTERFACE.\n", hr
);
3285 static void test_coop_level_surf_create(void)
3287 IDirectDrawSurface
*surface
;
3292 ddraw
= create_ddraw();
3293 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3295 memset(&ddsd
, 0, sizeof(ddsd
));
3296 ddsd
.dwSize
= sizeof(ddsd
);
3297 ddsd
.dwFlags
= DDSD_CAPS
;
3298 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3299 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3300 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
3302 IDirectDraw_Release(ddraw
);
3305 static void test_coop_level_multi_window(void)
3307 HWND window1
, window2
;
3311 window1
= CreateWindowA("static", "ddraw_test1", WS_OVERLAPPEDWINDOW
,
3312 0, 0, 640, 480, 0, 0, 0, 0);
3313 window2
= CreateWindowA("static", "ddraw_test2", WS_OVERLAPPEDWINDOW
,
3314 0, 0, 640, 480, 0, 0, 0, 0);
3315 ddraw
= create_ddraw();
3316 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3318 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
3319 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3320 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3321 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3322 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
3323 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
3325 IDirectDraw_Release(ddraw
);
3326 DestroyWindow(window2
);
3327 DestroyWindow(window1
);
3330 static void test_clear_rect_count(void)
3332 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3333 IDirect3DMaterial
*white
, *red
, *green
, *blue
;
3334 IDirect3DViewport
*viewport
;
3335 IDirect3DDevice
*device
;
3336 IDirectDrawSurface
*rt
;
3342 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3343 0, 0, 640, 480, 0, 0, 0, 0);
3344 ddraw
= create_ddraw();
3345 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3346 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3348 skip("Failed to create a 3D device, skipping test.\n");
3349 IDirectDraw_Release(ddraw
);
3350 DestroyWindow(window
);
3354 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
3355 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3357 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
3358 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
3359 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
3360 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
3361 viewport
= create_viewport(device
, 0, 0, 640, 480);
3363 viewport_set_background(device
, viewport
, white
);
3364 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
3365 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3366 viewport_set_background(device
, viewport
, red
);
3367 hr
= IDirect3DViewport_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
3368 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3369 viewport_set_background(device
, viewport
, green
);
3370 hr
= IDirect3DViewport_Clear(viewport
, 0, NULL
, D3DCLEAR_TARGET
);
3371 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3372 viewport_set_background(device
, viewport
, blue
);
3373 hr
= IDirect3DViewport_Clear(viewport
, 1, NULL
, D3DCLEAR_TARGET
);
3374 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3376 color
= get_surface_color(rt
, 320, 240);
3377 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x000000ff, 1)),
3378 "Got unexpected color 0x%08x.\n", color
);
3380 IDirectDrawSurface_Release(rt
);
3381 destroy_viewport(device
, viewport
);
3382 destroy_material(white
);
3383 destroy_material(red
);
3384 destroy_material(green
);
3385 destroy_material(blue
);
3386 IDirect3DDevice_Release(device
);
3387 IDirectDraw_Release(ddraw
);
3388 DestroyWindow(window
);
3397 } activateapp_testdata
;
3399 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
3401 if (message
== WM_ACTIVATEAPP
)
3403 if (activateapp_testdata
.ddraw
)
3406 activateapp_testdata
.received
= FALSE
;
3407 hr
= IDirectDraw_SetCooperativeLevel(activateapp_testdata
.ddraw
,
3408 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
3409 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#x.\n", hr
);
3410 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
3412 activateapp_testdata
.received
= TRUE
;
3415 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
3418 static void test_coop_level_activateapp(void)
3425 IDirectDrawSurface
*surface
;
3427 ddraw
= create_ddraw();
3428 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3430 wc
.lpfnWndProc
= activateapp_test_proc
;
3431 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
3432 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3434 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
3435 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
3437 /* Exclusive with window already active. */
3438 SetForegroundWindow(window
);
3439 activateapp_testdata
.received
= FALSE
;
3440 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3441 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3442 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
3443 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3444 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3446 /* Exclusive with window not active. */
3447 SetForegroundWindow(GetDesktopWindow());
3448 activateapp_testdata
.received
= FALSE
;
3449 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3450 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3451 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3452 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3453 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3455 /* Normal with window not active, then exclusive with the same window. */
3456 SetForegroundWindow(GetDesktopWindow());
3457 activateapp_testdata
.received
= FALSE
;
3458 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3459 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3460 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
3461 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3462 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3463 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3464 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3465 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3467 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
3468 SetForegroundWindow(GetDesktopWindow());
3469 activateapp_testdata
.received
= FALSE
;
3470 activateapp_testdata
.ddraw
= ddraw
;
3471 activateapp_testdata
.window
= window
;
3472 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
3473 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3474 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3475 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3476 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3477 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3479 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
3480 * succeeding. Another switch to exclusive and back to normal is needed to release the
3481 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
3482 * WM_ACTIVATEAPP messages. */
3483 activateapp_testdata
.ddraw
= NULL
;
3484 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3485 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3486 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3487 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3489 /* Setting DDSCL_NORMAL with recursive invocation. */
3490 SetForegroundWindow(GetDesktopWindow());
3491 activateapp_testdata
.received
= FALSE
;
3492 activateapp_testdata
.ddraw
= ddraw
;
3493 activateapp_testdata
.window
= window
;
3494 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
3495 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3496 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3497 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
3499 /* DDraw is in exclusive mode now. */
3500 memset(&ddsd
, 0, sizeof(ddsd
));
3501 ddsd
.dwSize
= sizeof(ddsd
);
3502 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
3503 ddsd
.dwBackBufferCount
= 1;
3504 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
3505 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3506 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
3507 IDirectDrawSurface_Release(surface
);
3509 /* Recover again, just to be sure. */
3510 activateapp_testdata
.ddraw
= NULL
;
3511 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3512 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3513 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3514 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3516 DestroyWindow(window
);
3517 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3518 IDirectDraw_Release(ddraw
);
3521 struct format_support_check
3523 const DDPIXELFORMAT
*format
;
3527 static HRESULT WINAPI
test_unsupported_formats_cb(DDSURFACEDESC
*desc
, void *ctx
)
3529 struct format_support_check
*format
= ctx
;
3531 if (!memcmp(format
->format
, &desc
->ddpfPixelFormat
, sizeof(*format
->format
)))
3533 format
->supported
= TRUE
;
3534 return DDENUMRET_CANCEL
;
3537 return DDENUMRET_OK
;
3540 static void test_unsupported_formats(void)
3543 BOOL expect_success
;
3546 IDirect3DDevice
*device
;
3547 IDirectDrawSurface
*surface
;
3550 DWORD expected_caps
;
3561 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
3562 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
3568 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
3569 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3573 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
3575 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3576 0, 0, 640, 480, 0, 0, 0, 0);
3577 ddraw
= create_ddraw();
3578 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3579 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3581 skip("Failed to create a 3D device, skipping test.\n");
3582 IDirectDraw_Release(ddraw
);
3583 DestroyWindow(window
);
3587 for (i
= 0; i
< sizeof(formats
) / sizeof(*formats
); i
++)
3589 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
3590 hr
= IDirect3DDevice_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
3591 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
3593 for (j
= 0; j
< sizeof(caps
) / sizeof(*caps
); j
++)
3595 memset(&ddsd
, 0, sizeof(ddsd
));
3596 ddsd
.dwSize
= sizeof(ddsd
);
3597 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
3598 ddsd
.ddpfPixelFormat
= formats
[i
].fmt
;
3601 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
3603 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
3604 expect_success
= FALSE
;
3606 expect_success
= TRUE
;
3608 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3609 ok(SUCCEEDED(hr
) == expect_success
,
3610 "Got unexpected hr %#x for format %s, caps %#x, expected %s.\n",
3611 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
3615 memset(&ddsd
, 0, sizeof(ddsd
));
3616 ddsd
.dwSize
= sizeof(ddsd
);
3617 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &ddsd
);
3618 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3620 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
3621 expected_caps
= DDSCAPS_VIDEOMEMORY
;
3622 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
3623 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
3624 else if (check
.supported
)
3625 expected_caps
= DDSCAPS_VIDEOMEMORY
;
3627 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
3629 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
3630 "Expected capability %#x, format %s, input cap %#x.\n",
3631 expected_caps
, formats
[i
].name
, caps
[j
]);
3633 IDirectDrawSurface_Release(surface
);
3637 IDirect3DDevice_Release(device
);
3638 IDirectDraw_Release(ddraw
);
3639 DestroyWindow(window
);
3642 static void test_rt_caps(void)
3644 PALETTEENTRY palette_entries
[256];
3645 IDirectDrawPalette
*palette
;
3646 IDirect3DDevice
*device
;
3654 static const DDPIXELFORMAT p8_fmt
=
3656 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
3657 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
3662 const DDPIXELFORMAT
*pf
;
3665 HRESULT create_device_hr
;
3666 BOOL create_may_fail
;
3672 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
3673 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3679 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
3680 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3686 DDSCAPS_OFFSCREENPLAIN
,
3687 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3693 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3694 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3695 D3DERR_SURFACENOTINVIDMEM
,
3700 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3701 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3707 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
3708 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3715 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3722 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3728 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3729 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3730 D3DERR_SURFACENOTINVIDMEM
,
3735 DDSCAPS_SYSTEMMEMORY
,
3736 DDSCAPS_SYSTEMMEMORY
,
3743 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3749 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
3750 ~0U /* AMD r200 */ ,
3751 DDERR_NOPALETTEATTACHED
,
3756 DDSCAPS_OFFSCREENPLAIN
,
3757 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
3763 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3764 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
3765 DDERR_NOPALETTEATTACHED
,
3770 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3771 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
3777 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
3778 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
3780 TRUE
/* AMD Evergreen */,
3784 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
3785 ~0U /* AMD Evergreen */,
3792 ~0U /* AMD Evergreen */,
3798 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
3799 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
3801 TRUE
/* Nvidia Kepler */,
3805 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
3806 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
3808 TRUE
/* Nvidia Kepler */,
3812 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3813 0, 0, 640, 480, 0, 0, 0, 0);
3814 ddraw
= create_ddraw();
3815 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3816 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
3818 skip("Failed to create a 3D device, skipping test.\n");
3819 IDirectDraw_Release(ddraw
);
3820 DestroyWindow(window
);
3823 z_depth
= get_device_z_depth(device
);
3824 ok(!!z_depth
, "Failed to get device z depth.\n");
3825 IDirect3DDevice_Release(device
);
3827 memset(palette_entries
, 0, sizeof(palette_entries
));
3828 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
3829 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
3831 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
3833 IDirectDrawSurface
*surface
;
3834 DDSURFACEDESC surface_desc
;
3835 IDirect3DDevice
*device
;
3837 memset(&surface_desc
, 0, sizeof(surface_desc
));
3838 surface_desc
.dwSize
= sizeof(surface_desc
);
3839 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
3840 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
3841 if (test_data
[i
].pf
)
3843 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
3844 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
3846 if (test_data
[i
].caps_in
& DDSCAPS_ZBUFFER
)
3848 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
3849 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
3851 surface_desc
.dwWidth
= 640;
3852 surface_desc
.dwHeight
= 480;
3853 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
3854 ok(SUCCEEDED(hr
) || broken(test_data
[i
].create_may_fail
),
3855 "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
3856 i
, test_data
[i
].caps_in
, hr
);
3860 memset(&surface_desc
, 0, sizeof(surface_desc
));
3861 surface_desc
.dwSize
= sizeof(surface_desc
);
3862 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
3863 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
3864 ok(test_data
[i
].caps_out
== ~0U || surface_desc
.ddsCaps
.dwCaps
== test_data
[i
].caps_out
,
3865 "Test %u: Got unexpected caps %#x, expected %#x.\n",
3866 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
3868 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DHALDevice
, (void **)&device
);
3869 ok(hr
== test_data
[i
].create_device_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n",
3870 i
, hr
, test_data
[i
].create_device_hr
);
3871 if (hr
== DDERR_NOPALETTEATTACHED
)
3873 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
3874 ok(SUCCEEDED(hr
), "Test %u: Failed to set palette, hr %#x.\n", i
, hr
);
3875 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DHALDevice
, (void **)&device
);
3876 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
3877 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
3879 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
3883 refcount
= IDirect3DDevice_Release(device
);
3884 ok(refcount
== 1, "Test %u: Got unexpected refcount %u.\n", i
, refcount
);
3887 refcount
= IDirectDrawSurface_Release(surface
);
3888 ok(refcount
== 0, "Test %u: The surface was not properly freed, refcount %u.\n", i
, refcount
);
3891 IDirectDrawPalette_Release(palette
);
3892 refcount
= IDirectDraw_Release(ddraw
);
3893 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
3894 DestroyWindow(window
);
3897 static void test_primary_caps(void)
3899 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
3900 IDirectDrawSurface
*surface
;
3901 DDSURFACEDESC surface_desc
;
3912 DWORD back_buffer_count
;
3920 DDSCAPS_PRIMARYSURFACE
,
3923 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
3927 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
3934 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
3937 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
3941 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
3948 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
3955 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
3962 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
3969 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
3976 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
3978 DDERR_NOEXCLUSIVEMODE
,
3982 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
3983 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
3989 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
3990 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
3993 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
3996 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
3997 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
4003 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4004 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
4011 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4012 0, 0, 640, 480, 0, 0, 0, 0);
4013 ddraw
= create_ddraw();
4014 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4016 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
4018 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
4019 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4021 memset(&surface_desc
, 0, sizeof(surface_desc
));
4022 surface_desc
.dwSize
= sizeof(surface_desc
);
4023 surface_desc
.dwFlags
= DDSD_CAPS
;
4024 if (test_data
[i
].back_buffer_count
!= ~0u)
4025 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
4026 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
4027 surface_desc
.dwBackBufferCount
= test_data
[i
].back_buffer_count
;
4028 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4029 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
4033 memset(&surface_desc
, 0, sizeof(surface_desc
));
4034 surface_desc
.dwSize
= sizeof(surface_desc
);
4035 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
4036 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
4037 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
4038 "Test %u: Got unexpected caps %#x, expected %#x.\n",
4039 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
4041 IDirectDrawSurface_Release(surface
);
4044 refcount
= IDirectDraw_Release(ddraw
);
4045 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4046 DestroyWindow(window
);
4049 static void test_surface_lock(void)
4052 IDirectDrawSurface
*surface
;
4053 IDirect3DDevice
*device
;
4068 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
4069 "videomemory offscreenplain"
4072 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4073 "systemmemory offscreenplain"
4076 DDSCAPS_PRIMARYSURFACE
,
4080 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
4081 "videomemory texture"
4084 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
4085 "systemmemory texture"
4088 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4097 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4098 0, 0, 640, 480, 0, 0, 0, 0);
4099 ddraw
= create_ddraw();
4100 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4101 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4103 skip("Failed to create a 3D device, skipping test.\n");
4104 IDirectDraw_Release(ddraw
);
4105 DestroyWindow(window
);
4108 z_depth
= get_device_z_depth(device
);
4109 ok(!!z_depth
, "Failed to get device z depth.\n");
4110 IDirect3DDevice_Release(device
);
4112 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
4114 memset(&ddsd
, 0, sizeof(ddsd
));
4115 ddsd
.dwSize
= sizeof(ddsd
);
4116 ddsd
.dwFlags
= DDSD_CAPS
;
4117 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
4119 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
4123 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
4125 ddsd
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4126 U2(ddsd
).dwZBufferBitDepth
= z_depth
;
4128 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
4130 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4131 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4133 memset(&ddsd
, 0, sizeof(ddsd
));
4134 ddsd
.dwSize
= sizeof(ddsd
);
4135 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
4136 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4139 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4140 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
4143 memset(&ddsd
, 0, sizeof(ddsd
));
4144 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
4145 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, tests
[i
].name
);
4147 IDirectDrawSurface_Release(surface
);
4150 refcount
= IDirectDraw_Release(ddraw
);
4151 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4152 DestroyWindow(window
);
4155 static void test_surface_discard(void)
4158 IDirect3DDevice
*device
;
4162 IDirectDrawSurface
*surface
, *target
;
4171 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, TRUE
},
4172 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
4173 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, TRUE
},
4174 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
4178 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4179 0, 0, 640, 480, 0, 0, 0, 0);
4180 ddraw
= create_ddraw();
4181 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4182 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4184 skip("Failed to create a 3D device, skipping test.\n");
4185 IDirectDraw_Release(ddraw
);
4186 DestroyWindow(window
);
4190 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&target
);
4191 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4193 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
4197 memset(&ddsd
, 0, sizeof(ddsd
));
4198 ddsd
.dwSize
= sizeof(ddsd
);
4199 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4200 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
4203 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4206 skip("Failed to create surface, skipping.\n");
4210 memset(&ddsd
, 0, sizeof(ddsd
));
4211 ddsd
.dwSize
= sizeof(ddsd
);
4212 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
4213 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4214 addr
= ddsd
.lpSurface
;
4215 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4216 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4218 memset(&ddsd
, 0, sizeof(ddsd
));
4219 ddsd
.dwSize
= sizeof(ddsd
);
4220 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
4221 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4222 discarded
= ddsd
.lpSurface
!= addr
;
4223 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4224 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4226 hr
= IDirectDrawSurface_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
4227 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
4229 memset(&ddsd
, 0, sizeof(ddsd
));
4230 ddsd
.dwSize
= sizeof(ddsd
);
4231 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
4232 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
4233 discarded
|= ddsd
.lpSurface
!= addr
;
4234 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
4235 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
4237 IDirectDrawSurface_Release(surface
);
4239 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
4240 * AMD r500, evergreen). Windows XP, at least on AMD r200, never changes the pointer. */
4241 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
4244 IDirectDrawSurface_Release(target
);
4245 IDirect3DDevice_Release(device
);
4246 IDirectDraw_Release(ddraw
);
4247 DestroyWindow(window
);
4250 static void test_flip(void)
4252 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
4253 IDirectDrawSurface
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
4254 DDSCAPS caps
= {DDSCAPS_FLIP
};
4255 DDSURFACEDESC surface_desc
;
4256 BOOL sysmem_primary
;
4258 DWORD expected_caps
;
4273 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
4274 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
4275 {"TEXTURE", DDSCAPS_TEXTURE
},
4278 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4279 0, 0, 640, 480, 0, 0, 0, 0);
4280 ddraw
= create_ddraw();
4281 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4283 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4284 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4286 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
4288 /* Creating a flippable texture induces a BSoD on some versions of the
4289 * Intel graphics driver. At least Intel GMA 950 with driver version
4290 * 6.14.10.4926 on Windows XP SP3 is affected. */
4291 if ((test_data
[i
].caps
& DDSCAPS_TEXTURE
) && ddraw_is_intel(ddraw
))
4293 win_skip("Skipping flippable texture test.\n");
4297 memset(&surface_desc
, 0, sizeof(surface_desc
));
4298 surface_desc
.dwSize
= sizeof(surface_desc
);
4299 surface_desc
.dwFlags
= DDSD_CAPS
;
4300 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
4301 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
4302 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
4303 surface_desc
.dwWidth
= 512;
4304 surface_desc
.dwHeight
= 512;
4305 surface_desc
.dwBackBufferCount
= 3;
4306 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
4307 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4309 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
4310 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
4311 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
4312 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4314 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
4315 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
4316 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
4317 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4319 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
4320 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
4321 todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
4322 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
4326 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
4327 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
4328 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
4329 ok(hr
== DD_OK
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4330 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
4331 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
4332 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4334 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
4335 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4336 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
4337 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
4338 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4339 hr
= restore_surfaces(ddraw
);
4340 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#x.\n", test_data
[i
].name
, hr
);
4342 memset(&surface_desc
, 0, sizeof(surface_desc
));
4343 surface_desc
.dwSize
= sizeof(surface_desc
);
4344 hr
= IDirectDrawSurface_GetSurfaceDesc(frontbuffer
, &surface_desc
);
4345 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
4346 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
4347 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
4348 expected_caps
|= DDSCAPS_VISIBLE
;
4349 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
4350 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
4351 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
4353 hr
= IDirectDrawSurface_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
4354 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
4355 memset(&surface_desc
, 0, sizeof(surface_desc
));
4356 surface_desc
.dwSize
= sizeof(surface_desc
);
4357 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer1
, &surface_desc
);
4358 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
4359 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
4360 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
4361 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
4362 expected_caps
|= DDSCAPS_BACKBUFFER
;
4363 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
4364 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
4366 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
4367 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
4368 memset(&surface_desc
, 0, sizeof(surface_desc
));
4369 surface_desc
.dwSize
= sizeof(surface_desc
);
4370 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer2
, &surface_desc
);
4371 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
4372 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
4373 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
4374 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
4375 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
4376 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
4378 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
4379 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
4380 memset(&surface_desc
, 0, sizeof(surface_desc
));
4381 surface_desc
.dwSize
= sizeof(surface_desc
);
4382 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer3
, &surface_desc
);
4383 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
4384 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
4385 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
4386 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
4387 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
4389 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
4390 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
4391 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
4392 test_data
[i
].name
, surface
, frontbuffer
);
4393 IDirectDrawSurface_Release(surface
);
4395 memset(&surface_desc
, 0, sizeof(surface_desc
));
4396 surface_desc
.dwSize
= sizeof(surface_desc
);
4397 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4398 surface_desc
.ddsCaps
.dwCaps
= 0;
4399 surface_desc
.dwWidth
= 640;
4400 surface_desc
.dwHeight
= 480;
4401 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4402 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
4403 hr
= IDirectDrawSurface_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
4404 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4405 IDirectDrawSurface_Release(surface
);
4407 hr
= IDirectDrawSurface_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
4408 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4409 hr
= IDirectDrawSurface_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
4410 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4411 hr
= IDirectDrawSurface_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
4412 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4413 hr
= IDirectDrawSurface_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
4414 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
4416 memset(&fx
, 0, sizeof(fx
));
4417 fx
.dwSize
= sizeof(fx
);
4418 U5(fx
).dwFillColor
= 0xffff0000;
4419 hr
= IDirectDrawSurface_Blt(backbuffer1
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4420 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
4421 U5(fx
).dwFillColor
= 0xff00ff00;
4422 hr
= IDirectDrawSurface_Blt(backbuffer2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4423 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
4424 U5(fx
).dwFillColor
= 0xff0000ff;
4425 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4426 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
4428 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
4429 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
4430 color
= get_surface_color(backbuffer1
, 320, 240);
4431 /* The testbot seems to just copy the contents of one surface to all the
4432 * others, instead of properly flipping. */
4433 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
4434 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4435 color
= get_surface_color(backbuffer2
, 320, 240);
4436 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4437 U5(fx
).dwFillColor
= 0xffff0000;
4438 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4439 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
4441 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
4442 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
4443 color
= get_surface_color(backbuffer1
, 320, 240);
4444 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
4445 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4446 color
= get_surface_color(backbuffer2
, 320, 240);
4447 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4448 U5(fx
).dwFillColor
= 0xff00ff00;
4449 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4450 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
4452 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
4453 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
4454 color
= get_surface_color(backbuffer1
, 320, 240);
4455 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
4456 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4457 color
= get_surface_color(backbuffer2
, 320, 240);
4458 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4459 U5(fx
).dwFillColor
= 0xff0000ff;
4460 hr
= IDirectDrawSurface_Blt(backbuffer3
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4461 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
4463 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
4464 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
4465 color
= get_surface_color(backbuffer2
, 320, 240);
4466 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
4467 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4468 color
= get_surface_color(backbuffer3
, 320, 240);
4469 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4470 U5(fx
).dwFillColor
= 0xffff0000;
4471 hr
= IDirectDrawSurface_Blt(backbuffer1
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4472 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
4474 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
4475 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
4476 color
= get_surface_color(backbuffer1
, 320, 240);
4477 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4478 color
= get_surface_color(backbuffer3
, 320, 240);
4479 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
4480 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4481 U5(fx
).dwFillColor
= 0xff00ff00;
4482 hr
= IDirectDrawSurface_Blt(backbuffer2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
4483 ok(SUCCEEDED(hr
), "%s: Failed to fill surface, hr %#x.\n", test_data
[i
].name
, hr
);
4485 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
4486 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
4487 color
= get_surface_color(backbuffer1
, 320, 240);
4488 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
4489 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4490 color
= get_surface_color(backbuffer2
, 320, 240);
4491 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
4493 IDirectDrawSurface_Release(backbuffer3
);
4494 IDirectDrawSurface_Release(backbuffer2
);
4495 IDirectDrawSurface_Release(backbuffer1
);
4496 IDirectDrawSurface_Release(frontbuffer
);
4499 refcount
= IDirectDraw_Release(ddraw
);
4500 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
4501 DestroyWindow(window
);
4504 static void test_sysmem_overlay(void)
4510 IDirectDrawSurface
*surface
;
4513 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4514 0, 0, 640, 480, 0, 0, 0, 0);
4515 ddraw
= create_ddraw();
4516 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4518 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4519 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4521 memset(&ddsd
, 0, sizeof(ddsd
));
4522 ddsd
.dwSize
= sizeof(ddsd
);
4523 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
4526 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
4527 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
4528 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4529 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
4530 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
4531 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
4532 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
4533 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4534 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#x.\n", hr
);
4536 ref
= IDirectDraw_Release(ddraw
);
4537 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
4538 DestroyWindow(window
);
4541 static void test_primary_palette(void)
4543 DDSCAPS surface_caps
= {DDSCAPS_FLIP
};
4544 IDirectDrawSurface
*primary
, *backbuffer
;
4545 PALETTEENTRY palette_entries
[256];
4546 IDirectDrawPalette
*palette
, *tmp
;
4547 DDSURFACEDESC surface_desc
;
4554 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4555 0, 0, 640, 480, 0, 0, 0, 0);
4556 ddraw
= create_ddraw();
4557 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4558 if (FAILED(IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 8)))
4560 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
4561 IDirectDraw_Release(ddraw
);
4562 DestroyWindow(window
);
4565 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4566 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4568 memset(&surface_desc
, 0, sizeof(surface_desc
));
4569 surface_desc
.dwSize
= sizeof(surface_desc
);
4570 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
4571 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
4572 surface_desc
.dwBackBufferCount
= 1;
4573 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
4574 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4575 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
4576 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
4578 memset(palette_entries
, 0, sizeof(palette_entries
));
4579 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
4580 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
4581 refcount
= get_refcount((IUnknown
*)palette
);
4582 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
4584 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
4585 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
4586 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
4588 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
4589 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
4591 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
4592 * and is generally somewhat broken with respect to 8 bpp / palette
4594 if (SUCCEEDED(IDirectDrawSurface_GetPalette(backbuffer
, &tmp
)))
4596 win_skip("Broken palette handling detected, skipping tests.\n");
4597 IDirectDrawPalette_Release(tmp
);
4598 IDirectDrawPalette_Release(palette
);
4599 /* The Windows 8 testbot keeps extra references to the primary and
4600 * backbuffer while in 8 bpp mode. */
4601 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
4602 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
4606 refcount
= get_refcount((IUnknown
*)palette
);
4607 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
4609 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
4610 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
4611 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
4612 "Got unexpected palette caps %#x.\n", palette_caps
);
4614 hr
= IDirectDrawSurface_SetPalette(primary
, NULL
);
4615 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
4616 refcount
= get_refcount((IUnknown
*)palette
);
4617 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
4619 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
4620 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
4621 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
4623 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
4624 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
4625 refcount
= get_refcount((IUnknown
*)palette
);
4626 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
4628 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
4629 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
4630 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
4631 IDirectDrawPalette_Release(tmp
);
4632 hr
= IDirectDrawSurface_GetPalette(backbuffer
, &tmp
);
4633 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
4635 refcount
= IDirectDrawPalette_Release(palette
);
4636 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
4637 refcount
= IDirectDrawPalette_Release(palette
);
4638 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
4640 /* Note that this only seems to work when the palette is attached to the
4641 * primary surface. When attached to a regular surface, attempting to get
4642 * the palette here will cause an access violation. */
4643 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
4644 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
4646 hr
= IDirectDrawSurface_IsLost(primary
);
4647 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
4649 memset(&surface_desc
, 0, sizeof(surface_desc
));
4650 surface_desc
.dwSize
= sizeof(surface_desc
);
4651 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
4652 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4653 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
4654 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
4655 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 8, "Got unexpected bit count %u.\n",
4656 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
4658 hr
= set_display_mode(ddraw
, 640, 480);
4659 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
4661 memset(&surface_desc
, 0, sizeof(surface_desc
));
4662 surface_desc
.dwSize
= sizeof(surface_desc
);
4663 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
4664 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4665 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
4666 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
4667 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 32
4668 || U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 24,
4669 "Got unexpected bit count %u.\n", U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
4671 hr
= IDirectDrawSurface_IsLost(primary
);
4672 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
4673 hr
= IDirectDrawSurface_Restore(primary
);
4674 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
4675 hr
= IDirectDrawSurface_IsLost(primary
);
4676 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
4678 memset(&surface_desc
, 0, sizeof(surface_desc
));
4679 surface_desc
.dwSize
= sizeof(surface_desc
);
4680 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
4681 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4682 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
4683 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
4684 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 32
4685 || U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 24,
4686 "Got unexpected bit count %u.\n", U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
4689 refcount
= IDirectDrawSurface_Release(backbuffer
);
4690 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
4691 refcount
= IDirectDrawSurface_Release(primary
);
4692 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
4693 refcount
= IDirectDraw_Release(ddraw
);
4694 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
4695 DestroyWindow(window
);
4698 static HRESULT WINAPI
surface_counter(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
4700 UINT
*surface_count
= context
;
4703 IDirectDrawSurface_Release(surface
);
4705 return DDENUMRET_OK
;
4708 static void test_surface_attachment(void)
4710 IDirectDrawSurface
*surface1
, *surface2
, *surface3
, *surface4
;
4711 DDSCAPS caps
= {DDSCAPS_TEXTURE
};
4712 DDSURFACEDESC surface_desc
;
4719 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4720 0, 0, 640, 480, 0, 0, 0, 0);
4721 ddraw
= create_ddraw();
4722 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4723 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4724 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4726 memset(&surface_desc
, 0, sizeof(surface_desc
));
4727 surface_desc
.dwSize
= sizeof(surface_desc
);
4728 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
4729 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
4730 U2(surface_desc
).dwMipMapCount
= 3;
4731 surface_desc
.dwWidth
= 128;
4732 surface_desc
.dwHeight
= 128;
4733 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
4734 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4736 hr
= IDirectDrawSurface_GetAttachedSurface(surface1
, &caps
, &surface2
);
4737 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
4738 hr
= IDirectDrawSurface_GetAttachedSurface(surface2
, &caps
, &surface3
);
4739 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
4740 hr
= IDirectDrawSurface_GetAttachedSurface(surface3
, &caps
, &surface4
);
4741 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
4744 IDirectDrawSurface_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
4745 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
4747 IDirectDrawSurface_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
4748 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
4750 IDirectDrawSurface_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
4751 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
4753 memset(&surface_desc
, 0, sizeof(surface_desc
));
4754 surface_desc
.dwSize
= sizeof(surface_desc
);
4755 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4756 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
4757 surface_desc
.dwWidth
= 16;
4758 surface_desc
.dwHeight
= 16;
4759 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
4760 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4762 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
4763 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4764 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
4765 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4766 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
4767 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4768 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
4769 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4770 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
4771 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4772 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
4773 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4775 IDirectDrawSurface_Release(surface4
);
4777 memset(&surface_desc
, 0, sizeof(surface_desc
));
4778 surface_desc
.dwSize
= sizeof(surface_desc
);
4779 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4780 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
4781 surface_desc
.dwWidth
= 16;
4782 surface_desc
.dwHeight
= 16;
4783 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
4784 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4786 if (SUCCEEDED(hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
)))
4788 skip("Running on refrast, skipping some tests.\n");
4789 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface4
);
4790 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
4794 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4795 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
4796 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4797 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
4798 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4799 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
4800 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4801 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
4802 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4803 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
4804 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4807 IDirectDrawSurface_Release(surface4
);
4808 IDirectDrawSurface_Release(surface3
);
4809 IDirectDrawSurface_Release(surface2
);
4810 IDirectDrawSurface_Release(surface1
);
4812 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4813 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4815 /* Try a single primary and two offscreen plain surfaces. */
4816 memset(&surface_desc
, 0, sizeof(surface_desc
));
4817 surface_desc
.dwSize
= sizeof(surface_desc
);
4818 surface_desc
.dwFlags
= DDSD_CAPS
;
4819 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4820 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
4821 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4823 memset(&surface_desc
, 0, sizeof(surface_desc
));
4824 surface_desc
.dwSize
= sizeof(surface_desc
);
4825 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4826 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
4827 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
4828 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
4829 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
4830 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4832 memset(&surface_desc
, 0, sizeof(surface_desc
));
4833 surface_desc
.dwSize
= sizeof(surface_desc
);
4834 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4835 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
4836 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
4837 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
4838 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
4839 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4841 /* This one has a different size. */
4842 memset(&surface_desc
, 0, sizeof(surface_desc
));
4843 surface_desc
.dwSize
= sizeof(surface_desc
);
4844 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4845 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
4846 surface_desc
.dwWidth
= 128;
4847 surface_desc
.dwHeight
= 128;
4848 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
4849 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4851 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
4852 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
4853 /* Try the reverse without detaching first. */
4854 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
4855 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
4856 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
4857 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
4859 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
4860 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
4861 /* Try to detach reversed. */
4862 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
4863 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4864 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface1
);
4865 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
4867 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface3
);
4868 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
4869 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface3
);
4870 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
4872 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
4873 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4874 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
4875 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
4877 IDirectDrawSurface_Release(surface4
);
4878 IDirectDrawSurface_Release(surface3
);
4879 IDirectDrawSurface_Release(surface2
);
4880 IDirectDrawSurface_Release(surface1
);
4882 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
4883 memset(&surface_desc
, 0, sizeof(surface_desc
));
4884 surface_desc
.dwSize
= sizeof(surface_desc
);
4885 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
4886 surface_desc
.dwWidth
= 64;
4887 surface_desc
.dwHeight
= 64;
4888 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
4889 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
4890 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
4891 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
4892 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
4893 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
4894 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
4895 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
4896 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4897 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
4898 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4900 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
4901 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
4902 U1(surface_desc
.ddpfPixelFormat
).dwZBufferBitDepth
= 16;
4903 U3(surface_desc
.ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
4904 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
4905 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4907 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
4908 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
4909 refcount
= get_refcount((IUnknown
*)surface2
);
4910 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
4911 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
4912 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
4914 /* Attaching while already attached to other surface. */
4915 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface2
);
4916 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
4917 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface3
, 0, surface2
);
4918 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
4919 IDirectDrawSurface_Release(surface3
);
4921 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
4922 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
4923 refcount
= get_refcount((IUnknown
*)surface2
);
4924 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
4926 /* Automatic detachment on release. */
4927 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
4928 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
4929 refcount
= get_refcount((IUnknown
*)surface2
);
4930 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
4931 refcount
= IDirectDrawSurface_Release(surface1
);
4932 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
4933 refcount
= IDirectDrawSurface_Release(surface2
);
4934 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
4935 refcount
= IDirectDraw_Release(ddraw
);
4936 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
4937 DestroyWindow(window
);
4940 static void test_pixel_format(void)
4942 HWND window
, window2
= NULL
;
4943 HDC hdc
, hdc2
= NULL
;
4945 int format
, test_format
;
4946 PIXELFORMATDESCRIPTOR pfd
;
4947 IDirectDraw
*ddraw
= NULL
;
4948 IDirectDrawClipper
*clipper
= NULL
;
4950 IDirectDrawSurface
*primary
= NULL
;
4954 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4955 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
4958 skip("Failed to create window\n");
4962 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4963 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
4965 hdc
= GetDC(window
);
4968 skip("Failed to get DC\n");
4973 hdc2
= GetDC(window2
);
4975 gl
= LoadLibraryA("opengl32.dll");
4976 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
4978 format
= GetPixelFormat(hdc
);
4979 ok(format
== 0, "new window has pixel format %d\n", format
);
4981 ZeroMemory(&pfd
, sizeof(pfd
));
4982 pfd
.nSize
= sizeof(pfd
);
4984 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
4985 pfd
.iPixelType
= PFD_TYPE_RGBA
;
4986 pfd
.iLayerType
= PFD_MAIN_PLANE
;
4987 format
= ChoosePixelFormat(hdc
, &pfd
);
4990 skip("no pixel format available\n");
4994 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
4996 skip("failed to set pixel format\n");
5000 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
5002 skip("failed to set pixel format on second window\n");
5005 ReleaseDC(window2
, hdc2
);
5010 ddraw
= create_ddraw();
5011 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5013 test_format
= GetPixelFormat(hdc
);
5014 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5016 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5019 skip("Failed to set cooperative level, hr %#x.\n", hr
);
5023 test_format
= GetPixelFormat(hdc
);
5024 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5028 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
5029 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
5030 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
5031 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
5033 test_format
= GetPixelFormat(hdc
);
5034 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5036 test_format
= GetPixelFormat(hdc2
);
5037 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5040 memset(&ddsd
, 0, sizeof(ddsd
));
5041 ddsd
.dwSize
= sizeof(ddsd
);
5042 ddsd
.dwFlags
= DDSD_CAPS
;
5043 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
5045 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
5046 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
5048 test_format
= GetPixelFormat(hdc
);
5049 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5053 test_format
= GetPixelFormat(hdc2
);
5054 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5059 hr
= IDirectDrawSurface_SetClipper(primary
, clipper
);
5060 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
5062 test_format
= GetPixelFormat(hdc
);
5063 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5065 test_format
= GetPixelFormat(hdc2
);
5066 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5069 memset(&fx
, 0, sizeof(fx
));
5070 fx
.dwSize
= sizeof(fx
);
5071 hr
= IDirectDrawSurface_Blt(primary
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
5072 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
5074 test_format
= GetPixelFormat(hdc
);
5075 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5079 test_format
= GetPixelFormat(hdc2
);
5080 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5084 if (primary
) IDirectDrawSurface_Release(primary
);
5085 if (clipper
) IDirectDrawClipper_Release(clipper
);
5086 if (ddraw
) IDirectDraw_Release(ddraw
);
5087 if (gl
) FreeLibrary(gl
);
5088 if (hdc
) ReleaseDC(window
, hdc
);
5089 if (hdc2
) ReleaseDC(window2
, hdc2
);
5090 if (window
) DestroyWindow(window
);
5091 if (window2
) DestroyWindow(window2
);
5094 static void test_create_surface_pitch(void)
5096 IDirectDrawSurface
*surface
;
5097 DDSURFACEDESC surface_desc
;
5118 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
5120 DDSD_PITCH
, 0x100, 0x100},
5121 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
5122 DDSD_PITCH
, 0x104, DD_OK
,
5123 DDSD_PITCH
, 0x100, 0x100},
5124 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
5125 DDSD_PITCH
, 0x0f8, DD_OK
,
5126 DDSD_PITCH
, 0x100, 0x100},
5127 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
5128 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
5130 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
5132 DDSD_PITCH
, 0x100, 0x0fc},
5134 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
5135 DDSD_PITCH
, 0x104, DD_OK
,
5136 DDSD_PITCH
, 0x100, 0x0fc},
5137 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
5138 DDSD_PITCH
, 0x0f8, DD_OK
,
5139 DDSD_PITCH
, 0x100, 0x0fc},
5140 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
5141 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
5142 DDSD_PITCH
, 0x100, 0x0fc},
5143 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
5144 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
5146 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
5147 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
5150 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
5151 0, 0, DDERR_INVALIDCAPS
,
5153 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
5155 DDSD_PITCH
, 0x100, 0 },
5156 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
5157 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
5159 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
5160 0, 0, DDERR_INVALIDCAPS
,
5162 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
5164 DDSD_PITCH
, 0x100, 0 },
5166 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
5167 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
5170 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
5172 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5173 0, 0, 640, 480, 0, 0, 0, 0);
5174 ddraw
= create_ddraw();
5175 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5176 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5177 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5179 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((63 * 4) + 8) * 63);
5181 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
5183 memset(&surface_desc
, 0, sizeof(surface_desc
));
5184 surface_desc
.dwSize
= sizeof(surface_desc
);
5185 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
5186 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
5187 surface_desc
.dwWidth
= 63;
5188 surface_desc
.dwHeight
= 63;
5189 U1(surface_desc
).lPitch
= test_data
[i
].pitch_in
;
5190 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5191 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5192 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5193 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5194 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5195 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5196 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5197 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
5199 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
5200 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, expected_hr
);
5201 surface_desc
.lpSurface
= mem
;
5202 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5204 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
5206 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
5210 memset(&surface_desc
, 0, sizeof(surface_desc
));
5211 surface_desc
.dwSize
= sizeof(surface_desc
);
5212 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
5213 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
5214 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
5215 "Test %u: Got unexpected flags %#x, expected %#x.\n",
5216 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
5217 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
5219 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
5220 todo_wine
ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out64
,
5221 "Test %u: Got unexpected pitch %u, expected %u.\n",
5222 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out64
);
5224 ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out32
,
5225 "Test %u: Got unexpected pitch %u, expected %u.\n",
5226 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out32
);
5228 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
5230 IDirectDrawSurface_Release(surface
);
5233 HeapFree(GetProcessHeap(), 0, mem
);
5234 refcount
= IDirectDraw_Release(ddraw
);
5235 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5236 DestroyWindow(window
);
5239 static void test_mipmap(void)
5241 IDirectDrawSurface
*surface
, *surface2
;
5242 DDSURFACEDESC surface_desc
;
5248 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
5257 DWORD mipmap_count_in
;
5259 DWORD mipmap_count_out
;
5263 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
5264 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
, 0},
5265 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
5266 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
, 0},
5267 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 6},
5268 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 6},
5271 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5272 0, 0, 640, 480, 0, 0, 0, 0);
5273 ddraw
= create_ddraw();
5274 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5275 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5276 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5278 memset(&hal_caps
, 0, sizeof(hal_caps
));
5279 hal_caps
.dwSize
= sizeof(hal_caps
);
5280 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
5281 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
5282 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
5284 skip("Mipmapped textures not supported, skipping tests.\n");
5285 IDirectDraw_Release(ddraw
);
5286 DestroyWindow(window
);
5290 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
5292 memset(&surface_desc
, 0, sizeof(surface_desc
));
5293 surface_desc
.dwSize
= sizeof(surface_desc
);
5294 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
5295 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
5296 surface_desc
.dwWidth
= tests
[i
].width
;
5297 surface_desc
.dwHeight
= tests
[i
].height
;
5298 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
5299 U2(surface_desc
).dwMipMapCount
= tests
[i
].mipmap_count_in
;
5300 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5301 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
5305 memset(&surface_desc
, 0, sizeof(surface_desc
));
5306 surface_desc
.dwSize
= sizeof(surface_desc
);
5307 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
5308 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
5309 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
5310 "Test %u: Got unexpected flags %#x.\n", i
, surface_desc
.dwFlags
);
5311 ok(U2(surface_desc
).dwMipMapCount
== tests
[i
].mipmap_count_out
,
5312 "Test %u: Got unexpected mipmap count %u.\n", i
, U2(surface_desc
).dwMipMapCount
);
5314 if (U2(surface_desc
).dwMipMapCount
> 1)
5316 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &surface2
);
5317 ok(SUCCEEDED(hr
), "Test %u: Failed to get attached surface, hr %#x.\n", i
, hr
);
5319 memset(&surface_desc
, 0, sizeof(surface_desc
));
5320 surface_desc
.dwSize
= sizeof(surface_desc
);
5321 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
5322 ok(SUCCEEDED(hr
), "Test %u: Failed to lock surface, hr %#x.\n", i
, hr
);
5323 memset(&surface_desc
, 0, sizeof(surface_desc
));
5324 surface_desc
.dwSize
= sizeof(surface_desc
);
5325 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &surface_desc
, 0, NULL
);
5326 ok(SUCCEEDED(hr
), "Test %u: Failed to lock surface, hr %#x.\n", i
, hr
);
5327 IDirectDrawSurface_Unlock(surface2
, NULL
);
5328 IDirectDrawSurface_Unlock(surface
, NULL
);
5330 IDirectDrawSurface_Release(surface2
);
5333 IDirectDrawSurface_Release(surface
);
5336 refcount
= IDirectDraw_Release(ddraw
);
5337 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5338 DestroyWindow(window
);
5341 static void test_palette_complex(void)
5343 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
5344 DDSURFACEDESC surface_desc
;
5346 IDirectDrawPalette
*palette
, *palette2
, *palette_mipmap
;
5350 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
5352 PALETTEENTRY palette_entries
[256];
5358 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5359 0, 0, 640, 480, 0, 0, 0, 0);
5360 ddraw
= create_ddraw();
5361 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5362 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5363 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5365 memset(&hal_caps
, 0, sizeof(hal_caps
));
5366 hal_caps
.dwSize
= sizeof(hal_caps
);
5367 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
5368 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
5369 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
5371 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
5372 IDirectDraw_Release(ddraw
);
5373 DestroyWindow(window
);
5377 memset(&surface_desc
, 0, sizeof(surface_desc
));
5378 surface_desc
.dwSize
= sizeof(surface_desc
);
5379 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5380 surface_desc
.dwWidth
= 128;
5381 surface_desc
.dwHeight
= 128;
5382 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
5383 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5384 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
5385 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
5386 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5387 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5389 memset(palette_entries
, 0, sizeof(palette_entries
));
5390 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
5391 palette_entries
, &palette
, NULL
);
5392 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
5394 memset(palette_entries
, 0, sizeof(palette_entries
));
5395 palette_entries
[1].peRed
= 0xff;
5396 palette_entries
[1].peGreen
= 0x80;
5397 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
5398 palette_entries
, &palette_mipmap
, NULL
);
5399 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
5401 palette2
= (void *)0xdeadbeef;
5402 hr
= IDirectDrawSurface_GetPalette(surface
, &palette2
);
5403 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
5404 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
5405 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
5406 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5407 hr
= IDirectDrawSurface_GetPalette(surface
, &palette2
);
5408 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
5409 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
5410 IDirectDrawPalette_Release(palette2
);
5413 IDirectDrawSurface_AddRef(mipmap
);
5414 for (i
= 0; i
< 7; ++i
)
5416 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
5417 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
5418 palette2
= (void *)0xdeadbeef;
5419 hr
= IDirectDrawSurface_GetPalette(tmp
, &palette2
);
5420 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
5421 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
5423 hr
= IDirectDrawSurface_SetPalette(tmp
, palette_mipmap
);
5424 ok(SUCCEEDED(hr
), "Failed to set palette, i %u, hr %#x.\n", i
, hr
);
5426 hr
= IDirectDrawSurface_GetPalette(tmp
, &palette2
);
5427 ok(SUCCEEDED(hr
), "Failed to get palette, i %u, hr %#x.\n", i
, hr
);
5428 ok(palette_mipmap
== palette2
, "Got unexpected palette %p.\n", palette2
);
5429 IDirectDrawPalette_Release(palette2
);
5431 hr
= IDirectDrawSurface_GetDC(tmp
, &dc
);
5432 ok(SUCCEEDED(hr
), "Failed to get DC, i %u, hr %#x.\n", i
, hr
);
5433 count
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
5434 ok(count
== 1, "Expected count 1, got %u.\n", count
);
5435 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x.\n", rgbquad
.rgbRed
);
5436 ok(rgbquad
.rgbGreen
== 0x80, "Expected rgbGreen = 0x80, got %#x.\n", rgbquad
.rgbGreen
);
5437 ok(rgbquad
.rgbBlue
== 0x0, "Expected rgbBlue = 0x0, got %#x.\n", rgbquad
.rgbBlue
);
5438 hr
= IDirectDrawSurface_ReleaseDC(tmp
, dc
);
5439 ok(SUCCEEDED(hr
), "Failed to release DC, i %u, hr %#x.\n", i
, hr
);
5441 IDirectDrawSurface_Release(mipmap
);
5445 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
5446 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
5447 IDirectDrawSurface_Release(mipmap
);
5448 refcount
= IDirectDrawSurface_Release(surface
);
5449 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5450 refcount
= IDirectDrawPalette_Release(palette_mipmap
);
5451 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5452 refcount
= IDirectDrawPalette_Release(palette
);
5453 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5455 refcount
= IDirectDraw_Release(ddraw
);
5456 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5457 DestroyWindow(window
);
5460 static void test_p8_blit(void)
5462 IDirectDrawSurface
*src
, *dst
, *dst_p8
;
5463 DDSURFACEDESC surface_desc
;
5465 IDirectDrawPalette
*palette
, *palette2
;
5469 PALETTEENTRY palette_entries
[256];
5473 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
5474 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
5475 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
5476 static const D3DCOLOR expected
[] =
5478 0x00101010, 0x00010101, 0x00020202, 0x00030303,
5479 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
5483 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5484 0, 0, 640, 480, 0, 0, 0, 0);
5485 ddraw
= create_ddraw();
5486 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5487 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5488 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5489 is_warp
= ddraw_is_warp(ddraw
);
5491 memset(palette_entries
, 0, sizeof(palette_entries
));
5492 palette_entries
[1].peGreen
= 0xff;
5493 palette_entries
[2].peBlue
= 0xff;
5494 palette_entries
[3].peFlags
= 0xff;
5495 palette_entries
[4].peRed
= 0xff;
5496 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
5497 palette_entries
, &palette
, NULL
);
5498 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
5499 palette_entries
[1].peBlue
= 0xff;
5500 palette_entries
[2].peGreen
= 0xff;
5501 palette_entries
[3].peRed
= 0xff;
5502 palette_entries
[4].peFlags
= 0x0;
5503 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
5504 palette_entries
, &palette2
, NULL
);
5505 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
5507 memset(&surface_desc
, 0, sizeof(surface_desc
));
5508 surface_desc
.dwSize
= sizeof(surface_desc
);
5509 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5510 surface_desc
.dwWidth
= 8;
5511 surface_desc
.dwHeight
= 1;
5512 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5513 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5514 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
5515 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
5516 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
5517 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5518 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
5519 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5520 hr
= IDirectDrawSurface_SetPalette(dst_p8
, palette2
);
5521 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5523 memset(&surface_desc
, 0, sizeof(surface_desc
));
5524 surface_desc
.dwSize
= sizeof(surface_desc
);
5525 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5526 surface_desc
.dwWidth
= 8;
5527 surface_desc
.dwHeight
= 1;
5528 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5529 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5530 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
5531 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5532 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5533 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5534 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5535 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
5536 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
5537 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5539 memset(&surface_desc
, 0, sizeof(surface_desc
));
5540 surface_desc
.dwSize
= sizeof(surface_desc
);
5541 hr
= IDirectDrawSurface_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
5542 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
5543 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
5544 hr
= IDirectDrawSurface_Unlock(src
, NULL
);
5545 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
5547 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
5548 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
5549 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
5550 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
5551 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
5553 hr
= IDirectDrawSurface_SetPalette(src
, palette
);
5554 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
5555 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
5556 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
5557 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
5558 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
5559 "Failed to blit, hr %#x.\n", hr
);
5563 for (x
= 0; x
< sizeof(expected
) / sizeof(*expected
); x
++)
5565 color
= get_surface_color(dst
, x
, 0);
5566 todo_wine
ok(compare_color(color
, expected
[x
], 0),
5567 "Pixel %u: Got color %#x, expected %#x.\n",
5568 x
, color
, expected
[x
]);
5572 memset(&fx
, 0, sizeof(fx
));
5573 fx
.dwSize
= sizeof(fx
);
5574 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
5575 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
5576 hr
= IDirectDrawSurface_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
5577 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
5579 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
5580 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
5581 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
5582 * surface untouched. P8 blits without color keys work. Error checking (DDBLT_KEYSRC without a key
5583 * for example) also works as expected.
5585 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
5586 * the display mode set to P8 doesn't help either. */
5587 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
5588 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
5589 "Got unexpected P8 color key blit result.\n");
5590 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
5591 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
5593 IDirectDrawSurface_Release(src
);
5594 IDirectDrawSurface_Release(dst
);
5595 IDirectDrawSurface_Release(dst_p8
);
5596 IDirectDrawPalette_Release(palette
);
5597 IDirectDrawPalette_Release(palette2
);
5599 refcount
= IDirectDraw_Release(ddraw
);
5600 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
5601 DestroyWindow(window
);
5604 static void test_material(void)
5606 IDirect3DMaterial
*background
, *material
;
5607 IDirect3DExecuteBuffer
*execute_buffer
;
5608 D3DMATERIALHANDLE mat_handle
, tmp
;
5609 D3DEXECUTEBUFFERDESC exec_desc
;
5610 IDirect3DViewport
*viewport
;
5611 IDirect3DDevice
*device
;
5612 IDirectDrawSurface
*rt
;
5623 static D3DVERTEX quad
[] =
5625 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5626 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5627 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5628 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5633 D3DCOLOR expected_color
;
5638 {FALSE
, 0x00ffffff},
5640 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
5642 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5643 0, 0, 640, 480, 0, 0, 0, 0);
5644 ddraw
= create_ddraw();
5645 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5646 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
5648 skip("Failed to create a 3D device, skipping test.\n");
5649 DestroyWindow(window
);
5653 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
5654 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
5656 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
5657 viewport
= create_viewport(device
, 0, 0, 640, 480);
5658 viewport_set_background(device
, viewport
, background
);
5660 material
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
5661 hr
= IDirect3DMaterial_GetHandle(material
, device
, &mat_handle
);
5662 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
5664 memset(&exec_desc
, 0, sizeof(exec_desc
));
5665 exec_desc
.dwSize
= sizeof(exec_desc
);
5666 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
5667 exec_desc
.dwBufferSize
= 1024;
5668 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
5670 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
5671 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
5673 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
5675 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
5676 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
5678 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
5679 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
5680 emit_set_ls(&ptr
, D3DLIGHTSTATE_MATERIAL
, test_data
[i
].material
? mat_handle
: 0);
5681 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, 4);
5682 emit_tquad(&ptr
, 0);
5684 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
5685 inst_length
-= sizeof(quad
);
5687 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
5688 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
5690 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
5691 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
5693 hr
= IDirect3DDevice_BeginScene(device
);
5694 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
5695 set_execute_data(execute_buffer
, 4, sizeof(quad
), inst_length
);
5696 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
5697 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
5698 hr
= IDirect3DDevice_EndScene(device
);
5699 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
5700 color
= get_surface_color(rt
, 320, 240);
5701 if (test_data
[i
].material
)
5702 todo_wine
ok(compare_color(color
, test_data
[i
].expected_color
, 1)
5703 /* The Windows 8 testbot appears to return undefined results. */
5705 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
5707 ok(compare_color(color
, test_data
[i
].expected_color
, 1),
5708 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
5711 destroy_material(material
);
5712 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
5713 hr
= IDirect3DMaterial_GetHandle(material
, device
, &mat_handle
);
5714 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
5716 hr
= IDirect3DViewport_SetBackground(viewport
, mat_handle
);
5717 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
5718 hr
= IDirect3DViewport_GetBackground(viewport
, &tmp
, &valid
);
5719 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
5720 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
5721 ok(valid
, "Got unexpected valid %#x.\n", valid
);
5722 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
5723 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
5724 color
= get_surface_color(rt
, 320, 240);
5725 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
5727 hr
= IDirect3DViewport_SetBackground(viewport
, 0);
5728 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
5729 hr
= IDirect3DViewport_GetBackground(viewport
, &tmp
, &valid
);
5730 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
5731 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
5732 ok(valid
, "Got unexpected valid %#x.\n", valid
);
5733 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
5734 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
5735 color
= get_surface_color(rt
, 320, 240);
5736 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
5738 destroy_viewport(device
, viewport
);
5739 viewport
= create_viewport(device
, 0, 0, 640, 480);
5741 hr
= IDirect3DViewport_GetBackground(viewport
, &tmp
, &valid
);
5742 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
5743 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
5744 ok(!valid
, "Got unexpected valid %#x.\n", valid
);
5745 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
5746 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
5747 color
= get_surface_color(rt
, 320, 240);
5748 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color
);
5750 IDirect3DExecuteBuffer_Release(execute_buffer
);
5751 destroy_viewport(device
, viewport
);
5752 destroy_material(background
);
5753 destroy_material(material
);
5754 IDirectDrawSurface_Release(rt
);
5755 refcount
= IDirect3DDevice_Release(device
);
5756 ok(!refcount
, "Device has %u references left.\n", refcount
);
5757 refcount
= IDirectDraw_Release(ddraw
);
5758 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
5759 DestroyWindow(window
);
5762 static void test_lighting(void)
5764 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
5765 static D3DMATRIX mat
=
5767 1.0f
, 0.0f
, 0.0f
, 0.0f
,
5768 0.0f
, 1.0f
, 0.0f
, 0.0f
,
5769 0.0f
, 0.0f
, 1.0f
, 0.0f
,
5770 0.0f
, 0.0f
, 0.0f
, 1.0f
,
5774 1.0f
, 0.0f
, 1.0f
, 0.0f
,
5775 0.0f
, 1.0f
, 0.0f
, 0.0f
,
5776 1.0f
, 0.0f
, 1.0f
, 0.0f
,
5777 0.0f
, 0.0f
, 0.5f
, 1.0f
,
5781 0.0f
, 0.0f
, 1.0f
, 0.0f
,
5782 0.0f
, 1.0f
, 0.0f
, 0.0f
,
5783 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
5784 10.f
, 10.0f
, 10.0f
, 1.0f
,
5788 1.0f
, 0.0f
, 0.0f
, 0.0f
,
5789 0.0f
, 1.0f
, 0.0f
, 0.0f
,
5790 0.0f
, 0.0f
, 1.0f
, -1.0f
,
5791 10.f
, 10.0f
, 10.0f
, 0.0f
,
5793 static D3DLVERTEX unlitquad
[] =
5795 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
5796 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
5797 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
5798 {{ 0.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
5802 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
5803 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
5804 {{ 0.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
5805 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
5807 static D3DVERTEX unlitnquad
[] =
5809 {{0.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5810 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5811 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5812 {{1.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5816 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5817 {{0.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5818 {{1.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5819 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5823 {{-1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
5824 {{-1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
5825 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
5826 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
5830 {{-10.0f
}, {-11.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
5831 {{-10.0f
}, { -9.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
5832 {{-10.0f
}, { -9.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
5833 {{-10.0f
}, {-11.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
5837 {{-11.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
5838 {{-11.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
5839 {{ -9.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
5840 {{ -9.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
5844 D3DMATRIX
*world_matrix
;
5847 const char *message
;
5851 {&mat
, nquad
, 0x000000ff, "Lit quad with light"},
5852 {&mat_singular
, nquad
, 0x000000b4, "Lit quad with singular world matrix"},
5853 {&mat_transf
, rotatedquad
, 0x000000ff, "Lit quad with transformation matrix"},
5854 {&mat_nonaffine
, translatedquad
, 0x000000ff, "Lit quad with non-affine matrix"},
5859 IDirect3DDevice
*device
;
5861 IDirectDrawSurface
*rt
;
5862 IDirect3DViewport
*viewport
;
5863 IDirect3DMaterial
*material
;
5864 IDirect3DLight
*light
;
5865 IDirect3DExecuteBuffer
*execute_buffer
;
5866 D3DEXECUTEBUFFERDESC exec_desc
;
5867 D3DMATERIALHANDLE mat_handle
;
5868 D3DMATRIXHANDLE world_handle
, view_handle
, proj_handle
;
5869 D3DLIGHT light_desc
;
5877 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
5878 0, 0, 640, 480, 0, 0, 0, 0);
5879 ddraw
= create_ddraw();
5880 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5881 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
5883 skip("Failed to create a 3D device, skipping test.\n");
5884 IDirectDraw_Release(ddraw
);
5885 DestroyWindow(window
);
5889 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
5890 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
5892 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
5893 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
5895 viewport
= create_viewport(device
, 0, 0, 640, 480);
5896 material
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
5897 viewport_set_background(device
, viewport
, material
);
5899 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
5900 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
5902 hr
= IDirect3DDevice_CreateMatrix(device
, &world_handle
);
5903 ok(hr
== D3D_OK
, "Creating a matrix object failed, hr %#x.\n", hr
);
5904 hr
= IDirect3DDevice_SetMatrix(device
, world_handle
, &mat
);
5905 ok(hr
== D3D_OK
, "Setting a matrix object failed, hr %#x.\n", hr
);
5906 hr
= IDirect3DDevice_CreateMatrix(device
, &view_handle
);
5907 ok(hr
== D3D_OK
, "Creating a matrix object failed, hr %#x.\n", hr
);
5908 hr
= IDirect3DDevice_SetMatrix(device
, view_handle
, &mat
);
5909 ok(hr
== D3D_OK
, "Setting a matrix object failed, hr %#x.\n", hr
);
5910 hr
= IDirect3DDevice_CreateMatrix(device
, &proj_handle
);
5911 ok(hr
== D3D_OK
, "Creating a matrix object failed, hr %#x.\n", hr
);
5912 hr
= IDirect3DDevice_SetMatrix(device
, proj_handle
, &mat
);
5913 ok(hr
== D3D_OK
, "Setting a matrix object failed, hr %#x.\n", hr
);
5915 memset(&exec_desc
, 0, sizeof(exec_desc
));
5916 exec_desc
.dwSize
= sizeof(exec_desc
);
5917 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
5918 exec_desc
.dwBufferSize
= 1024;
5919 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
5921 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
5922 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
5924 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
5925 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
5927 memcpy(exec_desc
.lpData
, unlitquad
, sizeof(unlitquad
));
5928 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(unlitquad
);
5929 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_WORLD
, world_handle
);
5930 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_VIEW
, view_handle
);
5931 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_PROJECTION
, proj_handle
);
5932 emit_set_rs(&ptr
, D3DRENDERSTATE_CLIPPING
, FALSE
);
5933 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
5934 emit_set_rs(&ptr
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
5935 emit_set_rs(&ptr
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
5936 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
5937 emit_tquad_tlist(&ptr
, 0);
5939 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
5940 inst_length
-= sizeof(unlitquad
);
5942 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
5943 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
5945 hr
= IDirect3DDevice_BeginScene(device
);
5946 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
5948 set_execute_data(execute_buffer
, 4, sizeof(unlitquad
), inst_length
);
5949 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
5950 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
5952 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
5953 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
5955 memcpy(exec_desc
.lpData
, litquad
, sizeof(litquad
));
5956 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(litquad
);
5957 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
5958 emit_tquad_tlist(&ptr
, 0);
5960 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
5961 inst_length
-= sizeof(litquad
);
5963 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
5964 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
5966 set_execute_data(execute_buffer
, 4, sizeof(litquad
), inst_length
);
5967 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
5968 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
5970 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
5971 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
5973 memcpy(exec_desc
.lpData
, unlitnquad
, sizeof(unlitnquad
));
5974 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(unlitnquad
);
5975 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, 4);
5976 emit_tquad_tlist(&ptr
, 0);
5978 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
5979 inst_length
-= sizeof(unlitnquad
);
5981 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
5982 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
5984 set_execute_data(execute_buffer
, 4, sizeof(unlitnquad
), inst_length
);
5985 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
5986 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
5988 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
5989 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
5991 memcpy(exec_desc
.lpData
, litnquad
, sizeof(litnquad
));
5992 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(litnquad
);
5993 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, 4);
5994 emit_tquad_tlist(&ptr
, 0);
5996 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
5997 inst_length
-= sizeof(litnquad
);
5999 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
6000 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
6002 set_execute_data(execute_buffer
, 4, sizeof(litnquad
), inst_length
);
6003 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
6004 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
6006 hr
= IDirect3DDevice_EndScene(device
);
6007 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6009 color
= get_surface_color(rt
, 160, 360);
6010 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color
);
6011 color
= get_surface_color(rt
, 160, 120);
6012 ok(color
== 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color
);
6013 color
= get_surface_color(rt
, 480, 360);
6014 ok(color
== 0x00ffffff, "Unlit quad with normals has color 0x%08x.\n", color
);
6015 color
= get_surface_color(rt
, 480, 120);
6016 ok(color
== 0x00ffffff, "Lit quad with normals has color 0x%08x.\n", color
);
6018 hr
= IDirect3DMaterial_GetHandle(material
, device
, &mat_handle
);
6019 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
6021 hr
= IDirect3D_CreateLight(d3d
, &light
, NULL
);
6022 ok(SUCCEEDED(hr
), "Failed to create a light object, hr %#x.\n", hr
);
6023 memset(&light_desc
, 0, sizeof(light_desc
));
6024 light_desc
.dwSize
= sizeof(light_desc
);
6025 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
6026 U1(light_desc
.dcvColor
).r
= 0.0f
;
6027 U2(light_desc
.dcvColor
).g
= 0.0f
;
6028 U3(light_desc
.dcvColor
).b
= 1.0f
;
6029 U4(light_desc
.dcvColor
).a
= 1.0f
;
6030 U3(light_desc
.dvDirection
).z
= 1.0f
;
6031 hr
= IDirect3DLight_SetLight(light
, &light_desc
);
6032 ok(SUCCEEDED(hr
), "Failed to set light, hr %#x.\n", hr
);
6033 hr
= IDirect3DViewport_AddLight(viewport
, light
);
6034 ok(SUCCEEDED(hr
), "Failed to add a light to the viewport, hr %#x.\n", hr
);
6036 for (i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); ++i
)
6038 hr
= IDirect3DDevice_SetMatrix(device
, world_handle
, tests
[i
].world_matrix
);
6039 ok(hr
== D3D_OK
, "Setting a matrix object failed, hr %#x.\n", hr
);
6041 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6042 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
6044 hr
= IDirect3DDevice_BeginScene(device
);
6045 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6047 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
6048 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
6050 memcpy(exec_desc
.lpData
, tests
[i
].quad
, sizeof(nquad
));
6051 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(nquad
);
6052 emit_set_ls(&ptr
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
6053 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, 4);
6054 emit_tquad_tlist(&ptr
, 0);
6056 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
6057 inst_length
-= sizeof(nquad
);
6059 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
6060 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
6062 set_execute_data(execute_buffer
, 4, sizeof(nquad
), inst_length
);
6063 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
6064 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
6066 hr
= IDirect3DDevice_EndScene(device
);
6067 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6069 color
= get_surface_color(rt
, 320, 240);
6070 todo_wine
ok(color
== tests
[i
].expected
, "%s has color 0x%08x.\n", tests
[i
].message
, color
);
6073 IDirect3DExecuteBuffer_Release(execute_buffer
);
6074 IDirect3DDevice_DeleteMatrix(device
, world_handle
);
6075 IDirect3DDevice_DeleteMatrix(device
, view_handle
);
6076 IDirect3DDevice_DeleteMatrix(device
, proj_handle
);
6077 hr
= IDirect3DViewport_DeleteLight(viewport
, light
);
6078 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#x.\n", hr
);
6079 IDirect3DLight_Release(light
);
6080 destroy_material(material
);
6081 destroy_viewport(device
, viewport
);
6082 IDirectDrawSurface_Release(rt
);
6083 refcount
= IDirect3DDevice_Release(device
);
6084 ok(!refcount
, "Device has %u references left.\n", refcount
);
6085 IDirect3D_Release(d3d
);
6086 refcount
= IDirectDraw_Release(ddraw
);
6087 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
6088 DestroyWindow(window
);
6091 static void test_palette_gdi(void)
6093 IDirectDrawSurface
*surface
, *primary
;
6094 DDSURFACEDESC surface_desc
;
6096 IDirectDrawPalette
*palette
, *palette2
;
6100 PALETTEENTRY palette_entries
[256];
6106 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
6107 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
6108 * not the point of this test. */
6109 static const RGBQUAD expected1
[] =
6111 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
6112 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
6114 static const RGBQUAD expected2
[] =
6116 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
6117 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
6119 static const RGBQUAD expected3
[] =
6121 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
6122 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
6124 HPALETTE ddraw_palette_handle
;
6125 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
6126 RGBQUAD rgbquad
[255];
6127 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
6129 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6130 0, 0, 640, 480, 0, 0, 0, 0);
6131 ddraw
= create_ddraw();
6132 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6133 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6134 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6136 memset(&surface_desc
, 0, sizeof(surface_desc
));
6137 surface_desc
.dwSize
= sizeof(surface_desc
);
6138 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6139 surface_desc
.dwWidth
= 16;
6140 surface_desc
.dwHeight
= 16;
6141 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6142 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6143 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
6144 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
6145 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6146 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6148 /* Avoid colors from the Windows default palette. */
6149 memset(palette_entries
, 0, sizeof(palette_entries
));
6150 palette_entries
[1].peRed
= 0x01;
6151 palette_entries
[2].peGreen
= 0x02;
6152 palette_entries
[3].peBlue
= 0x03;
6153 palette_entries
[4].peRed
= 0x13;
6154 palette_entries
[4].peGreen
= 0x14;
6155 palette_entries
[4].peBlue
= 0x15;
6156 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6157 palette_entries
, &palette
, NULL
);
6158 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6160 /* If there is no palette assigned and the display mode is not 8 bpp, some
6161 * drivers refuse to create a DC while others allow it. If a DC is created,
6162 * the DIB color table is uninitialized and contains random colors. No error
6163 * is generated when trying to read pixels and random garbage is returned.
6165 * The most likely explanation is that if the driver creates a DC, it (or
6166 * the higher-level runtime) uses GetSystemPaletteEntries to find the
6167 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
6168 * contains uninitialized garbage. See comments below for the P8 case. */
6170 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
6171 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6172 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
6173 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6174 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
6175 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
6176 "Got unexpected palette %p, expected %p.\n",
6177 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
6179 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
6180 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
6181 for (i
= 0; i
< sizeof(expected1
) / sizeof(*expected1
); i
++)
6183 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
6184 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6185 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
6186 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
6188 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
6190 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
6191 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
6192 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
6195 /* Update the palette while the DC is in use. This does not modify the DC. */
6196 palette_entries
[4].peRed
= 0x23;
6197 palette_entries
[4].peGreen
= 0x24;
6198 palette_entries
[4].peBlue
= 0x25;
6199 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
6200 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#x.\n", hr
);
6202 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
6203 ok(i
== 1, "Expected count 1, got %u.\n", i
);
6204 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
6205 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6206 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
6207 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
6209 /* Neither does re-setting the palette. */
6210 hr
= IDirectDrawSurface_SetPalette(surface
, NULL
);
6211 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6212 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
6213 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6215 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
6216 ok(i
== 1, "Expected count 1, got %u.\n", i
);
6217 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
6218 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6219 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
6220 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
6222 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
6223 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6225 /* Refresh the DC. This updates the palette. */
6226 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
6227 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6228 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
6229 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
6230 for (i
= 0; i
< sizeof(expected2
) / sizeof(*expected2
); i
++)
6232 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
6233 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6234 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
6235 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
6237 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
6239 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
6240 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
6241 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
6243 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
6244 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6246 refcount
= IDirectDrawSurface_Release(surface
);
6247 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6249 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
6250 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6251 if (FAILED(IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 8)))
6253 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
6254 IDirectDrawPalette_Release(palette
);
6255 IDirectDraw_Release(ddraw
);
6256 DestroyWindow(window
);
6259 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
6261 memset(&surface_desc
, 0, sizeof(surface_desc
));
6262 surface_desc
.dwSize
= sizeof(surface_desc
);
6263 surface_desc
.dwFlags
= DDSD_CAPS
;
6264 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
6265 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
6266 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6268 memset(&fx
, 0, sizeof(fx
));
6269 fx
.dwSize
= sizeof(fx
);
6270 U5(fx
).dwFillColor
= 3;
6271 SetRect(&r
, 0, 0, 319, 479);
6272 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
6273 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
6274 SetRect(&r
, 320, 0, 639, 479);
6275 U5(fx
).dwFillColor
= 4;
6276 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
6277 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
6279 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
6280 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6281 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
6282 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6284 color
= GetPixel(dc
, 160, 240);
6285 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
6286 color
= GetPixel(dc
, 480, 240);
6287 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
6289 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
6290 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
6291 "Got unexpected palette %p, expected %p.\n",
6292 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
6293 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
6295 /* The primary uses the system palette. In exclusive mode, the system palette matches
6296 * the ddraw palette attached to the primary, so the result is what you would expect
6297 * from a regular surface. Tests for the interaction between the ddraw palette and
6298 * the system palette are not included pending an application that depends on this.
6299 * The relation between those causes problems on Windows Vista and newer for games
6300 * like Age of Empires or StarCraft. Don't emulate it without a real need. */
6301 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
6302 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
6303 for (i
= 0; i
< sizeof(expected2
) / sizeof(*expected2
); i
++)
6305 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
6306 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6307 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
6308 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
6310 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
6312 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
6313 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
6314 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
6316 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
6317 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6319 memset(&surface_desc
, 0, sizeof(surface_desc
));
6320 surface_desc
.dwSize
= sizeof(surface_desc
);
6321 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6322 surface_desc
.dwWidth
= 16;
6323 surface_desc
.dwHeight
= 16;
6324 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6325 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6326 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6328 /* Here the offscreen surface appears to use the primary's palette,
6329 * but in all likelihood it is actually the system palette. */
6330 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
6331 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6332 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
6333 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
6334 for (i
= 0; i
< sizeof(expected2
) / sizeof(*expected2
); i
++)
6336 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
6337 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6338 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
6339 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
6341 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
6343 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
6344 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
6345 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
6347 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
6348 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6350 /* On real hardware a change to the primary surface's palette applies immediately,
6351 * even on device contexts from offscreen surfaces that do not have their own
6352 * palette. On the testbot VMs this is not the case. Don't test this until we
6353 * know of an application that depends on this. */
6355 memset(palette_entries
, 0, sizeof(palette_entries
));
6356 palette_entries
[1].peBlue
= 0x40;
6357 palette_entries
[2].peRed
= 0x40;
6358 palette_entries
[3].peGreen
= 0x40;
6359 palette_entries
[4].peRed
= 0x12;
6360 palette_entries
[4].peGreen
= 0x34;
6361 palette_entries
[4].peBlue
= 0x56;
6362 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6363 palette_entries
, &palette2
, NULL
);
6364 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6365 hr
= IDirectDrawSurface_SetPalette(surface
, palette2
);
6366 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6368 /* A palette assigned to the offscreen surface overrides the primary / system
6370 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
6371 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6372 i
= GetDIBColorTable(dc
, 0, sizeof(rgbquad
) / sizeof(*rgbquad
), rgbquad
);
6373 ok(i
== sizeof(rgbquad
) / sizeof(*rgbquad
), "Expected count 255, got %u.\n", i
);
6374 for (i
= 0; i
< sizeof(expected3
) / sizeof(*expected3
); i
++)
6376 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
6377 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
6378 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
6379 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
6381 for (; i
< sizeof(rgbquad
) / sizeof(*rgbquad
); i
++)
6383 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
6384 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
6385 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
6387 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
6388 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6390 refcount
= IDirectDrawSurface_Release(surface
);
6391 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6393 /* The Windows 8 testbot keeps extra references to the primary and
6394 * backbuffer while in 8 bpp mode. */
6395 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
6396 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
6398 refcount
= IDirectDrawSurface_Release(primary
);
6399 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6400 refcount
= IDirectDrawPalette_Release(palette2
);
6401 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6402 refcount
= IDirectDrawPalette_Release(palette
);
6403 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6404 refcount
= IDirectDraw_Release(ddraw
);
6405 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6406 DestroyWindow(window
);
6409 static void test_palette_alpha(void)
6411 IDirectDrawSurface
*surface
;
6412 DDSURFACEDESC surface_desc
;
6414 IDirectDrawPalette
*palette
;
6418 PALETTEENTRY palette_entries
[256];
6423 BOOL attach_allowed
;
6428 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
6429 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
6430 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
6433 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6434 0, 0, 640, 480, 0, 0, 0, 0);
6435 ddraw
= create_ddraw();
6436 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6437 if (FAILED(IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 8)))
6439 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
6440 IDirectDraw_Release(ddraw
);
6441 DestroyWindow(window
);
6444 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6445 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6447 memset(palette_entries
, 0, sizeof(palette_entries
));
6448 palette_entries
[1].peFlags
= 0x42;
6449 palette_entries
[2].peFlags
= 0xff;
6450 palette_entries
[3].peFlags
= 0x80;
6451 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
6452 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6454 memset(palette_entries
, 0x66, sizeof(palette_entries
));
6455 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
6456 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
6457 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
6458 palette_entries
[0].peFlags
);
6459 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
6460 palette_entries
[1].peFlags
);
6461 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
6462 palette_entries
[2].peFlags
);
6463 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
6464 palette_entries
[3].peFlags
);
6466 IDirectDrawPalette_Release(palette
);
6468 memset(palette_entries
, 0, sizeof(palette_entries
));
6469 palette_entries
[1].peFlags
= 0x42;
6470 palette_entries
[1].peRed
= 0xff;
6471 palette_entries
[2].peFlags
= 0xff;
6472 palette_entries
[3].peFlags
= 0x80;
6473 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
6474 palette_entries
, &palette
, NULL
);
6475 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6477 memset(palette_entries
, 0x66, sizeof(palette_entries
));
6478 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
6479 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
6480 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
6481 palette_entries
[0].peFlags
);
6482 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
6483 palette_entries
[1].peFlags
);
6484 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
6485 palette_entries
[2].peFlags
);
6486 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
6487 palette_entries
[3].peFlags
);
6489 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); i
++)
6491 memset(&surface_desc
, 0, sizeof(surface_desc
));
6492 surface_desc
.dwSize
= sizeof(surface_desc
);
6493 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
6494 surface_desc
.dwWidth
= 128;
6495 surface_desc
.dwHeight
= 128;
6496 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
6497 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6498 ok(SUCCEEDED(hr
), "Failed to create %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
6500 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
6501 if (test_data
[i
].attach_allowed
)
6502 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
6504 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
6512 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
6513 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_CANTCREATEDC
) /* Win2k testbot */,
6514 "Failed to get DC, hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
6517 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
6518 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
6519 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
6520 rgbquad
.rgbRed
, test_data
[i
].name
);
6521 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
6522 rgbquad
.rgbGreen
, test_data
[i
].name
);
6523 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
6524 rgbquad
.rgbBlue
, test_data
[i
].name
);
6525 ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
6526 rgbquad
.rgbReserved
, test_data
[i
].name
);
6527 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
6528 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6531 IDirectDrawSurface_Release(surface
);
6534 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
6535 memset(&surface_desc
, 0, sizeof(surface_desc
));
6536 surface_desc
.dwSize
= sizeof(surface_desc
);
6537 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6538 surface_desc
.dwWidth
= 128;
6539 surface_desc
.dwHeight
= 128;
6540 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6541 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6542 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6543 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6544 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6545 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6546 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6547 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6548 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6549 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
6550 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
6551 IDirectDrawSurface_Release(surface
);
6553 /* The Windows 8 testbot keeps extra references to the primary
6554 * while in 8 bpp mode. */
6555 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
6556 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
6558 refcount
= IDirectDrawPalette_Release(palette
);
6559 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6560 refcount
= IDirectDraw_Release(ddraw
);
6561 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6562 DestroyWindow(window
);
6565 static void test_lost_device(void)
6567 IDirectDrawSurface
*surface
;
6568 DDSURFACEDESC surface_desc
;
6569 HWND window1
, window2
;
6575 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6576 0, 0, 640, 480, 0, 0, 0, 0);
6577 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6578 0, 0, 640, 480, 0, 0, 0, 0);
6579 ddraw
= create_ddraw();
6580 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6581 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6582 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6584 memset(&surface_desc
, 0, sizeof(surface_desc
));
6585 surface_desc
.dwSize
= sizeof(surface_desc
);
6586 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
6587 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
6588 surface_desc
.dwBackBufferCount
= 1;
6589 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6590 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6592 hr
= IDirectDrawSurface_IsLost(surface
);
6593 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6594 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6595 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6597 ret
= SetForegroundWindow(GetDesktopWindow());
6598 ok(ret
, "Failed to set foreground window.\n");
6599 hr
= IDirectDrawSurface_IsLost(surface
);
6600 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6601 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6602 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6604 ret
= SetForegroundWindow(window1
);
6605 ok(ret
, "Failed to set foreground window.\n");
6606 hr
= IDirectDrawSurface_IsLost(surface
);
6607 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6608 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6609 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6611 hr
= restore_surfaces(ddraw
);
6612 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6613 hr
= IDirectDrawSurface_IsLost(surface
);
6614 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6615 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6616 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6618 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
6619 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6620 hr
= IDirectDrawSurface_IsLost(surface
);
6621 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6622 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6623 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
6625 /* Trying to restore the primary will crash, probably because flippable
6626 * surfaces can't exist in DDSCL_NORMAL. */
6627 IDirectDrawSurface_Release(surface
);
6628 memset(&surface_desc
, 0, sizeof(surface_desc
));
6629 surface_desc
.dwSize
= sizeof(surface_desc
);
6630 surface_desc
.dwFlags
= DDSD_CAPS
;
6631 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
6632 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6633 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6635 hr
= IDirectDrawSurface_IsLost(surface
);
6636 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6638 ret
= SetForegroundWindow(GetDesktopWindow());
6639 ok(ret
, "Failed to set foreground window.\n");
6640 hr
= IDirectDrawSurface_IsLost(surface
);
6641 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6643 ret
= SetForegroundWindow(window1
);
6644 ok(ret
, "Failed to set foreground window.\n");
6645 hr
= IDirectDrawSurface_IsLost(surface
);
6646 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6648 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6649 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6650 hr
= IDirectDrawSurface_IsLost(surface
);
6651 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6653 hr
= restore_surfaces(ddraw
);
6654 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6655 hr
= IDirectDrawSurface_IsLost(surface
);
6656 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6658 IDirectDrawSurface_Release(surface
);
6659 memset(&surface_desc
, 0, sizeof(surface_desc
));
6660 surface_desc
.dwSize
= sizeof(surface_desc
);
6661 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
6662 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
6663 surface_desc
.dwBackBufferCount
= 1;
6664 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6665 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6667 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6668 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6669 hr
= IDirectDrawSurface_IsLost(surface
);
6670 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6671 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6672 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6674 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
6675 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6676 hr
= IDirectDrawSurface_IsLost(surface
);
6677 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6678 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6679 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
6681 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
6682 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6683 hr
= IDirectDrawSurface_IsLost(surface
);
6684 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6685 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6686 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
6688 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
6689 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6690 hr
= IDirectDrawSurface_IsLost(surface
);
6691 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6692 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6693 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
6695 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
6696 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6697 hr
= IDirectDrawSurface_IsLost(surface
);
6698 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6699 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6700 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
6702 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6703 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6704 hr
= IDirectDrawSurface_IsLost(surface
);
6705 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6706 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
6707 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6709 IDirectDrawSurface_Release(surface
);
6710 refcount
= IDirectDraw_Release(ddraw
);
6711 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6712 DestroyWindow(window2
);
6713 DestroyWindow(window1
);
6716 static void test_surface_desc_lock(void)
6718 IDirectDrawSurface
*surface
;
6719 DDSURFACEDESC surface_desc
;
6725 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6726 0, 0, 640, 480, 0, 0, 0, 0);
6727 ddraw
= create_ddraw();
6728 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6729 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6730 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6732 memset(&surface_desc
, 0, sizeof(surface_desc
));
6733 surface_desc
.dwSize
= sizeof(surface_desc
);
6734 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6735 surface_desc
.dwWidth
= 16;
6736 surface_desc
.dwHeight
= 16;
6737 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6738 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6739 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6741 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
6742 surface_desc
.dwSize
= sizeof(surface_desc
);
6743 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
6744 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6745 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
6747 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
6748 surface_desc
.dwSize
= sizeof(surface_desc
);
6749 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
6750 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6751 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
6752 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
6753 surface_desc
.dwSize
= sizeof(surface_desc
);
6754 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
6755 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6756 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
6757 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
6758 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6760 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
6761 surface_desc
.dwSize
= sizeof(surface_desc
);
6762 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
6763 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6764 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
6766 IDirectDrawSurface_Release(surface
);
6767 refcount
= IDirectDraw_Release(ddraw
);
6768 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6769 DestroyWindow(window
);
6772 static void test_texturemapblend(void)
6776 D3DEXECUTEBUFFERDESC exec_desc
;
6778 static RECT rect
= {0, 0, 64, 128};
6779 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
6781 IDirectDrawSurface
*surface
, *rt
;
6782 IDirect3DTexture
*texture
;
6783 D3DTEXTUREHANDLE texture_handle
;
6786 IDirect3DDevice
*device
;
6787 IDirect3DMaterial
*material
;
6788 IDirect3DViewport
*viewport
;
6789 IDirect3DExecuteBuffer
*execute_buffer
;
6795 static const D3DTLVERTEX test1_quads
[] =
6797 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {0.0f
}},
6798 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {1.0f
}},
6799 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {0.0f
}},
6800 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {1.0f
}},
6801 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {0.0f
}},
6802 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {1.0f
}},
6803 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {0.0f
}},
6804 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {1.0f
}},
6808 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {0.0f
}},
6809 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {1.0f
}},
6810 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {0.0f
}},
6811 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {1.0f
}},
6812 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {0.0f
}},
6813 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {1.0f
}},
6814 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {0.0f
}},
6815 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {1.0f
}},
6818 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
6819 0, 0, 640, 480, 0, 0, 0, 0);
6820 ddraw
= create_ddraw();
6821 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6822 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
6824 skip("Failed to create a 3D device, skipping test.\n");
6825 DestroyWindow(window
);
6826 IDirectDraw_Release(ddraw
);
6830 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
6831 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
6833 material
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
6834 viewport
= create_viewport(device
, 0, 0, 640, 480);
6835 viewport_set_background(device
, viewport
, material
);
6837 memset(&exec_desc
, 0, sizeof(exec_desc
));
6838 exec_desc
.dwSize
= sizeof(exec_desc
);
6839 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
6840 exec_desc
.dwBufferSize
= 1024;
6841 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
6842 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
6843 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
6845 /* Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel.
6847 * The vertex alpha is completely ignored in this case, so case 1 and 2 combined are not
6848 * a D3DTOP_MODULATE with texture alpha = 0xff in case 2 (no alpha in texture). */
6849 memset(&ddsd
, 0, sizeof(ddsd
));
6850 ddsd
.dwSize
= sizeof(ddsd
);
6851 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
6852 ddsd
.dwHeight
= 128;
6854 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6855 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6856 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
6857 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6858 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6859 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6860 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6861 U5(ddsd
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
6862 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6863 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6865 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
6866 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
6867 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
6868 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
6870 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6871 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
6873 memset(&fx
, 0, sizeof(fx
));
6874 fx
.dwSize
= sizeof(fx
);
6875 U5(fx
).dwFillColor
= 0xff0000ff;
6876 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
6877 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
6878 U5(fx
).dwFillColor
= 0x800000ff;
6879 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
6880 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
6882 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
6883 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
6885 memcpy(exec_desc
.lpData
, test1_quads
, sizeof(test1_quads
));
6887 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(test1_quads
);
6888 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
6889 emit_set_rs(&ptr
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
6890 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
6891 emit_set_rs(&ptr
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
6892 emit_set_rs(&ptr
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
6893 /* The history of D3DRENDERSTATE_ALPHABLENDENABLE is quite a mess. In the
6894 * first D3D release there was a D3DRENDERSTATE_BLENDENABLE (enum value 27).
6895 * D3D5 introduced a new and separate D3DRENDERSTATE_ALPHABLENDENABLE (42)
6896 * together with D3DRENDERSTATE_COLORKEYENABLE (41). The docs aren't all
6897 * that clear but they mention that D3DRENDERSTATE_BLENDENABLE overrides the
6899 * Then D3D6 came and got rid of the new D3DRENDERSTATE_ALPHABLENDENABLE
6900 * state (42), renaming the older D3DRENDERSTATE_BLENDENABLE enum (27)
6901 * as D3DRENDERSTATE_ALPHABLENDENABLE.
6902 * There is a comment in the D3D6 docs which mentions that hardware
6903 * rasterizers always used D3DRENDERSTATE_BLENDENABLE to just toggle alpha
6904 * blending while prior to D3D5 software rasterizers toggled both color
6905 * keying and alpha blending according to it. What I gather is that, from
6906 * D3D6 onwards, D3DRENDERSTATE_ALPHABLENDENABLE always only toggles the
6907 * alpha blending state.
6908 * These tests seem to show that actual, current hardware follows the D3D6
6909 * behavior even when using the original D3D interfaces, for the HAL device
6911 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
6912 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
6913 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
6915 emit_tquad(&ptr
, 0);
6916 emit_tquad(&ptr
, 4);
6919 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
6920 inst_length
-= sizeof(test1_quads
);
6921 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
6922 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
6923 set_execute_data(execute_buffer
, 8, sizeof(test1_quads
), inst_length
);
6925 hr
= IDirect3DDevice_BeginScene(device
);
6926 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6927 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
6928 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
6929 hr
= IDirect3DDevice_EndScene(device
);
6930 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
6932 color
= get_surface_color(rt
, 5, 5);
6933 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
6934 color
= get_surface_color(rt
, 400, 5);
6935 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
6936 color
= get_surface_color(rt
, 5, 245);
6937 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
6938 color
= get_surface_color(rt
, 400, 245);
6939 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
6941 IDirect3DTexture_Release(texture
);
6942 ref
= IDirectDrawSurface_Release(surface
);
6943 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
6945 /* Test alpha with texture that has no alpha channel - alpha should be taken from diffuse vertex color. */
6946 memset(&ddsd
, 0, sizeof(ddsd
));
6947 ddsd
.dwSize
= sizeof(ddsd
);
6948 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
6949 ddsd
.dwHeight
= 128;
6951 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6952 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6953 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6954 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6955 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6956 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6957 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6959 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6960 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6962 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
6963 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
6964 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
6965 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
6967 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6968 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
6970 U5(fx
).dwFillColor
= 0xff0000ff;
6971 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
6972 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
6973 U5(fx
).dwFillColor
= 0x800000ff;
6974 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
6975 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
6977 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
6978 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
6980 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(test1_quads
);
6981 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
6982 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
6984 emit_tquad(&ptr
, 0);
6985 emit_tquad(&ptr
, 4);
6988 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
6989 inst_length
-= sizeof(test1_quads
);
6990 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
6991 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
6992 set_execute_data(execute_buffer
, 8, sizeof(test1_quads
), inst_length
);
6994 hr
= IDirect3DDevice_BeginScene(device
);
6995 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
6996 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
6997 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
6998 hr
= IDirect3DDevice_EndScene(device
);
6999 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7001 color
= get_surface_color(rt
, 5, 5);
7002 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
7003 color
= get_surface_color(rt
, 400, 5);
7004 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
7005 color
= get_surface_color(rt
, 5, 245);
7006 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
7007 color
= get_surface_color(rt
, 400, 245);
7008 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
7010 IDirect3DTexture_Release(texture
);
7011 ref
= IDirectDrawSurface_Release(surface
);
7012 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
7014 /* Test RGB - should multiply color components from diffuse vertex color and texture. */
7015 memset(&ddsd
, 0, sizeof(ddsd
));
7016 ddsd
.dwSize
= sizeof(ddsd
);
7017 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
7018 ddsd
.dwHeight
= 128;
7020 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
7021 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
7022 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
7023 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
7024 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7025 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7026 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7027 U5(ddsd
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
7028 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7029 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7031 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
7032 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
7033 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
7034 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
7036 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7037 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
7039 U5(fx
).dwFillColor
= 0x00ffffff;
7040 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7041 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
7042 U5(fx
).dwFillColor
= 0x00ffff80;
7043 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7044 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
7046 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
7047 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
7049 memcpy(exec_desc
.lpData
, test2_quads
, sizeof(test2_quads
));
7051 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(test2_quads
);
7052 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
7053 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
7054 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
7056 emit_tquad(&ptr
, 0);
7057 emit_tquad(&ptr
, 4);
7060 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
7061 inst_length
-= sizeof(test2_quads
);
7062 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
7063 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
7064 set_execute_data(execute_buffer
, 8, sizeof(test2_quads
), inst_length
);
7066 hr
= IDirect3DDevice_BeginScene(device
);
7067 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7068 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
7069 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
7070 hr
= IDirect3DDevice_EndScene(device
);
7071 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7073 /* WARP (Win8 testbot) emulates color keying with the alpha channel like Wine does,
7074 * but even applies it when there's no color key assigned. The surface alpha is zero
7075 * here, so nothing gets drawn.
7077 * The ddraw2 version of this test draws these quads with color keying off due to
7078 * different defaults in ddraw1 and ddraw2. */
7079 color
= get_surface_color(rt
, 5, 5);
7080 ok(compare_color(color
, 0x00ff0040, 2) || broken(compare_color(color
, 0x00000000, 1)),
7081 "Got unexpected color 0x%08x.\n", color
);
7082 color
= get_surface_color(rt
, 400, 5);
7083 ok(compare_color(color
, 0x00ff0080, 2) || broken(compare_color(color
, 0x00000000, 1)),
7084 "Got unexpected color 0x%08x.\n", color
);
7085 color
= get_surface_color(rt
, 5, 245);
7086 ok(compare_color(color
, 0x00800080, 2) || broken(compare_color(color
, 0x00000000, 1)),
7087 "Got unexpected color 0x%08x.\n", color
);
7088 color
= get_surface_color(rt
, 400, 245);
7089 ok(compare_color(color
, 0x008000ff, 2) || broken(compare_color(color
, 0x00000000, 1)),
7090 "Got unexpected color 0x%08x.\n", color
);
7092 IDirect3DTexture_Release(texture
);
7093 ref
= IDirectDrawSurface_Release(surface
);
7094 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
7096 /* Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere). */
7097 memset(&ddsd
, 0, sizeof(ddsd
));
7098 ddsd
.dwSize
= sizeof(ddsd
);
7099 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
7100 ddsd
.dwHeight
= 128;
7102 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
7103 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
7104 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7105 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 16;
7106 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
7107 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
7108 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
7110 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7111 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7113 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
7114 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
7115 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
7116 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
7118 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7119 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
7121 U5(fx
).dwFillColor
= 0xf800;
7122 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7123 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
7124 U5(fx
).dwFillColor
= 0x001f;
7125 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7126 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
7128 ckey
.dwColorSpaceLowValue
= 0x001f;
7129 ckey
.dwColorSpaceHighValue
= 0x001f;
7130 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
7131 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
7133 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
7134 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
7136 memcpy(exec_desc
.lpData
, test1_quads
, sizeof(test1_quads
));
7138 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(test1_quads
);
7139 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
7140 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
7141 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
7142 /* D3DRENDERSTATE_COLORKEYENABLE is supposed to be on by default on version
7143 * 1 devices, but for some reason it randomly defaults to FALSE on the W8
7144 * testbot. This is either the fault of Windows 8 or the WARP driver.
7145 * Also D3DRENDERSTATE_COLORKEYENABLE was introduced in D3D 5 aka version 2
7146 * devices only, which might imply this doesn't actually do anything on
7148 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
7150 emit_tquad(&ptr
, 0);
7151 emit_tquad(&ptr
, 4);
7154 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
7155 inst_length
-= sizeof(test1_quads
);
7156 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
7157 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
7158 set_execute_data(execute_buffer
, 8, sizeof(test1_quads
), inst_length
);
7160 hr
= IDirect3DDevice_BeginScene(device
);
7161 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7162 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
7163 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
7164 hr
= IDirect3DDevice_EndScene(device
);
7165 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7167 /* Allow broken WARP results (colorkey disabled). */
7168 color
= get_surface_color(rt
, 5, 5);
7169 ok(compare_color(color
, 0x00000000, 2) || broken(compare_color(color
, 0x000000ff, 2)),
7170 "Got unexpected color 0x%08x.\n", color
);
7171 color
= get_surface_color(rt
, 400, 5);
7172 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
7173 color
= get_surface_color(rt
, 5, 245);
7174 ok(compare_color(color
, 0x00000000, 2) || broken(compare_color(color
, 0x00000080, 2)),
7175 "Got unexpected color 0x%08x.\n", color
);
7176 color
= get_surface_color(rt
, 400, 245);
7177 ok(compare_color(color
, 0x00800000, 2), "Got unexpected color 0x%08x.\n", color
);
7179 IDirect3DTexture_Release(texture
);
7180 ref
= IDirectDrawSurface_Release(surface
);
7181 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
7183 ref
= IDirect3DExecuteBuffer_Release(execute_buffer
);
7184 ok(ref
== 0, "Execute buffer not properly released, refcount %u.\n", ref
);
7185 destroy_viewport(device
, viewport
);
7186 ref
= IDirect3DMaterial_Release(material
);
7187 ok(ref
== 0, "Material not properly released, refcount %u.\n", ref
);
7188 IDirectDrawSurface_Release(rt
);
7189 IDirect3DDevice_Release(device
);
7190 ref
= IDirectDraw_Release(ddraw
);
7191 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
7192 DestroyWindow(window
);
7195 static void test_viewport_clear_rect(void)
7198 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
7199 static D3DRECT clear_rect2
= {{90}, {90}, {110}, {110}};
7200 IDirectDrawSurface
*rt
;
7203 IDirect3DDevice
*device
;
7204 IDirect3DMaterial
*red
, *green
;
7205 IDirect3DViewport
*viewport
, *viewport2
;
7209 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
7210 0, 0, 640, 480, 0, 0, 0, 0);
7211 ddraw
= create_ddraw();
7212 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7213 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7215 skip("Failed to create a 3D device, skipping test.\n");
7216 DestroyWindow(window
);
7217 IDirectDraw_Release(ddraw
);
7221 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
7222 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
7224 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
7225 viewport
= create_viewport(device
, 0, 0, 640, 480);
7226 viewport_set_background(device
, viewport
, red
);
7227 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7228 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
7230 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
7231 viewport2
= create_viewport(device
, 100, 100, 20, 20);
7232 viewport_set_background(device
, viewport2
, green
);
7233 hr
= IDirect3DViewport_Clear(viewport2
, 1, &clear_rect2
, D3DCLEAR_TARGET
);
7234 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
7236 color
= get_surface_color(rt
, 85, 85); /* Outside both. */
7237 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
7238 color
= get_surface_color(rt
, 95, 95); /* Outside vp, inside rect. */
7239 /* AMD GPUs ignore the viewport dimensions and only care about the rectangle. */
7240 ok(compare_color(color
, 0x00ff0000, 1) || broken(compare_color(color
, 0x0000ff00, 1)),
7241 "Got unexpected color 0x%08x.\n", color
);
7242 color
= get_surface_color(rt
, 105, 105); /* Inside both. */
7243 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
7244 color
= get_surface_color(rt
, 115, 115); /* Inside vp, outside rect. */
7245 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
7246 color
= get_surface_color(rt
, 125, 125); /* Outside both. */
7247 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
7249 destroy_viewport(device
, viewport2
);
7250 destroy_material(green
);
7251 destroy_viewport(device
, viewport
);
7252 destroy_material(red
);
7253 IDirectDrawSurface_Release(rt
);
7254 IDirect3DDevice_Release(device
);
7255 ref
= IDirectDraw_Release(ddraw
);
7256 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
7257 DestroyWindow(window
);
7260 static void test_color_fill(void)
7263 IDirect3DDevice
*device
;
7265 IDirectDrawSurface
*surface
, *surface2
;
7266 DDSURFACEDESC surface_desc
;
7271 RECT rect
= {5, 5, 7, 7};
7273 DWORD num_fourcc_codes
, *fourcc_codes
;
7275 BOOL support_uyvy
= FALSE
, support_yuy2
= FALSE
;
7279 HRESULT colorfill_hr
, depthfill_hr
;
7284 DDPIXELFORMAT format
;
7289 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
7290 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
7292 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
7293 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
7297 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
7298 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
7300 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
7301 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
7305 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
7306 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
7308 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
7309 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
7313 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
7314 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
7316 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
7317 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
7321 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
,
7322 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0, FALSE
,
7323 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
7326 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
7327 * different afterwards. DX9+ GPUs set one of the two luminance values
7328 * in each block, but AMD and Nvidia GPUs disagree on which luminance
7329 * value they set. r200 (dx8) just sets the entire block to the clear
7331 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
7332 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
7334 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
7335 {0}, {0}, {0}, {0}, {0}
7339 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
7340 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
7342 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
7343 {0}, {0}, {0}, {0}, {0}
7347 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
7348 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
7350 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
7351 {0}, {0}, {0}, {0}, {0}
7355 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
7356 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
7358 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
7359 {0}, {0}, {0}, {0}, {0}
7363 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
7364 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
7366 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
7367 {0}, {0}, {0}, {0}, {0}
7371 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
7372 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
7374 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
7375 {0}, {0}, {0}, {0}, {0}
7379 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
7380 * surface works, presumably because it is handled by the runtime instead of
7382 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
7383 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
7385 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
7386 {8}, {0}, {0}, {0}, {0}
7390 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
7391 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
7393 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
7394 {8}, {0}, {0}, {0}, {0}
7406 {SRCCOPY
, "SRCCOPY", DD_OK
},
7407 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
7408 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
7409 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
7410 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
7411 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
7412 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
7413 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
7414 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
7415 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
7416 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
7417 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
7418 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
7419 {BLACKNESS
, "BLACKNESS", DD_OK
},
7420 {WHITENESS
, "WHITENESS", DD_OK
},
7421 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
7424 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
7425 0, 0, 640, 480, 0, 0, 0, 0);
7426 ddraw
= create_ddraw();
7427 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7428 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7430 skip("Failed to create a 3D device, skipping test.\n");
7431 DestroyWindow(window
);
7432 IDirectDraw_Release(ddraw
);
7436 hr
= IDirectDraw_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
7437 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
7438 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
7439 num_fourcc_codes
* sizeof(*fourcc_codes
));
7442 hr
= IDirectDraw_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
7443 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
7444 for (i
= 0; i
< num_fourcc_codes
; i
++)
7446 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
7447 support_yuy2
= TRUE
;
7448 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
7449 support_uyvy
= TRUE
;
7451 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
7453 memset(&hal_caps
, 0, sizeof(hal_caps
));
7454 hal_caps
.dwSize
= sizeof(hal_caps
);
7455 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
7456 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
7458 if ((!support_yuy2
&& !support_uyvy
) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
7459 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
7461 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); i
++)
7463 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
7464 memset(&fx
, 0, sizeof(fx
));
7465 fx
.dwSize
= sizeof(fx
);
7466 U5(fx
).dwFillColor
= 0xdeadbeef;
7468 memset(&surface_desc
, 0, sizeof(surface_desc
));
7469 surface_desc
.dwSize
= sizeof(surface_desc
);
7470 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7471 surface_desc
.dwWidth
= 64;
7472 surface_desc
.dwHeight
= 64;
7473 surface_desc
.ddpfPixelFormat
= tests
[i
].format
;
7474 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
7476 if (tests
[i
].caps
& DDSCAPS_TEXTURE
)
7478 struct format_support_check check
= {&tests
[i
].format
, FALSE
};
7479 hr
= IDirect3DDevice_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
7480 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
7481 if (!check
.supported
)
7485 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !support_yuy2
)
7487 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !support_uyvy
)
7489 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
7492 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
7494 surface_desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
7495 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
7496 U2(surface_desc
).dwZBufferBitDepth
= get_device_z_depth(device
);
7499 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7500 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
7502 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7503 todo_wine_if (tests
[i
].format
.dwFourCC
)
7504 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
7505 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
7507 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7508 todo_wine_if (tests
[i
].format
.dwFourCC
)
7509 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
7510 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
7512 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
7514 memset(&surface_desc
, 0, sizeof(surface_desc
));
7515 surface_desc
.dwSize
= sizeof(surface_desc
);
7516 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
7517 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
7518 color
= surface_desc
.lpSurface
;
7519 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
7520 *color
, tests
[i
].result
, tests
[i
].name
);
7521 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
7522 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
7525 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7526 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
7527 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
7528 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7529 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
7530 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
7532 U5(fx
).dwFillColor
= 0xdeadbeef;
7533 fx
.dwROP
= BLACKNESS
;
7534 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
7535 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
7536 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
7537 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
7538 U5(fx
).dwFillColor
, tests
[i
].name
);
7540 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
7542 memset(&surface_desc
, 0, sizeof(surface_desc
));
7543 surface_desc
.dwSize
= sizeof(surface_desc
);
7544 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
7545 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
7546 color
= surface_desc
.lpSurface
;
7547 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
7548 *color
, tests
[i
].name
);
7549 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
7550 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
7553 fx
.dwROP
= WHITENESS
;
7554 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
7555 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
7556 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
7557 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
7558 U5(fx
).dwFillColor
, tests
[i
].name
);
7560 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
7562 memset(&surface_desc
, 0, sizeof(surface_desc
));
7563 surface_desc
.dwSize
= sizeof(surface_desc
);
7564 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
7565 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
7566 color
= surface_desc
.lpSurface
;
7567 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
7568 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
7569 *color
, tests
[i
].name
);
7570 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
7571 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
7574 IDirectDrawSurface_Release(surface
);
7577 memset(&fx
, 0, sizeof(fx
));
7578 fx
.dwSize
= sizeof(fx
);
7579 U5(fx
).dwFillColor
= 0xdeadbeef;
7580 fx
.dwROP
= WHITENESS
;
7582 memset(&surface_desc
, 0, sizeof(surface_desc
));
7583 surface_desc
.dwSize
= sizeof(surface_desc
);
7584 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7585 surface_desc
.dwWidth
= 64;
7586 surface_desc
.dwHeight
= 64;
7587 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7588 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7589 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
7590 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7591 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7592 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7593 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
7594 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7595 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7596 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
7597 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7600 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
7601 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7602 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
7603 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7605 /* Unused source rectangle. */
7606 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7607 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
7608 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
7609 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
7611 /* Unused source surface. */
7612 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7613 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7614 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
7615 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
7616 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7617 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7618 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
7619 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
7621 /* Inverted destination or source rectangle. */
7622 SetRect(&rect
, 5, 7, 7, 5);
7623 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7624 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
7625 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7626 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
7627 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7628 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7629 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7630 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7631 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
7632 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
7634 /* Negative rectangle. */
7635 SetRect(&rect
, -1, -1, 5, 5);
7636 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7637 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
7638 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7639 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
7640 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7641 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7642 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7643 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7644 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
7645 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
7647 /* Out of bounds rectangle. */
7648 SetRect(&rect
, 0, 0, 65, 65);
7649 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7650 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
7651 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
7652 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
7654 /* Combine multiple flags. */
7655 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7656 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
7657 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
7658 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7659 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
7660 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7662 for (i
= 0; i
< sizeof(rops
) / sizeof(*rops
); i
++)
7664 fx
.dwROP
= rops
[i
].rop
;
7665 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
7666 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#x for rop %s.\n", hr
, rops
[i
].name
);
7669 IDirectDrawSurface_Release(surface2
);
7670 IDirectDrawSurface_Release(surface
);
7672 memset(&surface_desc
, 0, sizeof(surface_desc
));
7673 surface_desc
.dwSize
= sizeof(surface_desc
);
7674 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_ZBUFFERBITDEPTH
;
7675 surface_desc
.dwWidth
= 64;
7676 surface_desc
.dwHeight
= 64;
7677 U2(surface_desc
).dwZBufferBitDepth
= get_device_z_depth(device
);
7678 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
7679 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7680 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7681 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
7682 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7685 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
7686 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7688 /* Unused source rectangle. */
7689 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7690 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
7692 /* Unused source surface. */
7693 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7694 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7695 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7696 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7698 /* Inverted destination or source rectangle. */
7699 SetRect(&rect
, 5, 7, 7, 5);
7700 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7701 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
7702 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7703 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
7704 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7705 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7706 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7707 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7709 /* Negative rectangle. */
7710 SetRect(&rect
, -1, -1, 5, 5);
7711 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7712 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
7713 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7714 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
7715 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7716 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7717 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7718 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7720 /* Out of bounds rectangle. */
7721 SetRect(&rect
, 0, 0, 65, 65);
7722 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7723 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
7725 /* Combine multiple flags. */
7726 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
7727 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7729 IDirectDrawSurface_Release(surface2
);
7730 IDirectDrawSurface_Release(surface
);
7733 IDirect3DDevice_Release(device
);
7734 refcount
= IDirectDraw_Release(ddraw
);
7735 ok(refcount
== 0, "Ddraw object not properly released, refcount %u.\n", refcount
);
7736 DestroyWindow(window
);
7739 static void test_colorkey_precision(void)
7741 static D3DTLVERTEX quad
[] =
7743 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x00000000}, {0x00000000}, {0.0f
}, {1.0f
}},
7744 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0x00000000}, {0x00000000}, {0.0f
}, {0.0f
}},
7745 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x00000000}, {0x00000000}, {1.0f
}, {1.0f
}},
7746 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0x00000000}, {0x00000000}, {1.0f
}, {0.0f
}},
7748 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
7749 IDirect3DDevice
*device
;
7751 IDirectDrawSurface
*rt
;
7752 IDirect3DViewport
*viewport
;
7753 IDirect3DExecuteBuffer
*execute_buffer
;
7754 D3DEXECUTEBUFFERDESC exec_desc
;
7759 IDirectDrawSurface
*src
, *dst
, *texture
;
7760 D3DTEXTUREHANDLE handle
;
7761 IDirect3DTexture
*d3d_texture
;
7762 IDirect3DMaterial
*green
;
7763 DDSURFACEDESC surface_desc
, lock_desc
;
7769 DWORD data
[4] = {0}, color_mask
;
7770 BOOL is_nvidia
, is_warp
;
7773 unsigned int max
, shift
, bpp
, clear
;
7781 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
7783 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
7784 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
7789 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
7791 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
7792 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
7797 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
7799 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
7800 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
7805 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
7807 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
7808 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
7813 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
7814 0, 0, 640, 480, 0, 0, 0, 0);
7815 ddraw
= create_ddraw();
7816 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7817 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7819 skip("Failed to create a 3D device, skipping test.\n");
7820 DestroyWindow(window
);
7821 IDirectDraw_Release(ddraw
);
7824 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
7825 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
7827 is_nvidia
= ddraw_is_nvidia(ddraw
);
7828 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
7829 * (color key doesn't match although the values are equal), and a false
7830 * positive when the color key is 0 and the texture contains the value 1.
7831 * I don't want to mark this broken unconditionally since this would
7832 * essentially disable the test on Windows. Also on random occasions
7833 * 254 == 255 and 255 != 255.*/
7834 is_warp
= ddraw_is_warp(ddraw
);
7836 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
7837 viewport
= create_viewport(device
, 0, 0, 640, 480);
7838 viewport_set_background(device
, viewport
, green
);
7840 memset(&exec_desc
, 0, sizeof(exec_desc
));
7841 exec_desc
.dwSize
= sizeof(exec_desc
);
7842 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
7843 exec_desc
.dwBufferSize
= 1024;
7844 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
7845 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
7846 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
7848 memset(&fx
, 0, sizeof(fx
));
7849 fx
.dwSize
= sizeof(fx
);
7850 memset(&lock_desc
, 0, sizeof(lock_desc
));
7851 lock_desc
.dwSize
= sizeof(lock_desc
);
7853 for (t
= 0; t
< sizeof(tests
) / sizeof(*tests
); ++t
)
7855 if (is_nvidia
&& tests
[t
].skip_nv
)
7857 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
7861 memset(&surface_desc
, 0, sizeof(surface_desc
));
7862 surface_desc
.dwSize
= sizeof(surface_desc
);
7863 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7864 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7865 surface_desc
.dwWidth
= 4;
7866 surface_desc
.dwHeight
= 1;
7867 surface_desc
.ddpfPixelFormat
= tests
[t
].fmt
;
7868 /* Windows XP (at least with the r200 driver, other drivers untested) produces
7869 * garbage when doing color keyed texture->texture blits. */
7870 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
7871 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7872 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
7873 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7875 U5(fx
).dwFillColor
= tests
[t
].clear
;
7876 /* On the w8 testbot (WARP driver) the blit result has different values in the
7878 color_mask
= U2(tests
[t
].fmt
).dwRBitMask
7879 | U3(tests
[t
].fmt
).dwGBitMask
7880 | U4(tests
[t
].fmt
).dwBBitMask
;
7882 for (c
= 0; c
<= tests
[t
].max
; ++c
)
7884 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
7885 * texture after it has been set once... */
7886 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
7887 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
7888 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
7889 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
7890 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
7891 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7893 hr
= IDirectDrawSurface_QueryInterface(texture
, &IID_IDirect3DTexture
, (void **)&d3d_texture
);
7894 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
7895 hr
= IDirect3DTexture_GetHandle(d3d_texture
, device
, &handle
);
7896 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
7897 IDirect3DTexture_Release(d3d_texture
);
7899 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
7900 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
7902 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
7904 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
7905 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
7906 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
7907 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, handle
);
7908 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATEALPHA
);
7909 /* D3DRENDERSTATE_COLORKEYENABLE is supposed to be on by default on version
7910 * 1 devices, but for some reason it randomly defaults to FALSE on the W8
7911 * testbot. This is either the fault of Windows 8 or the WARP driver.
7912 * Also D3DRENDERSTATE_COLORKEYENABLE was introduced in D3D 5 aka version 2
7913 * devices only, which might imply this doesn't actually do anything on
7915 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
7917 emit_tquad(&ptr
, 0);
7918 emit_tquad(&ptr
, 4);
7919 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
7922 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
7923 inst_length
-= sizeof(quad
);
7924 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
7925 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
7926 set_execute_data(execute_buffer
, 8, sizeof(quad
), inst_length
);
7928 hr
= IDirectDrawSurface_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7929 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
7931 hr
= IDirectDrawSurface_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
7932 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
7933 switch (tests
[t
].bpp
)
7936 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
7937 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
7938 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
7939 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
7943 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
7944 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
7945 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
7946 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
7949 hr
= IDirectDrawSurface_Unlock(src
, 0);
7950 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
7951 hr
= IDirectDrawSurface_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
7952 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
7954 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
7955 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
7956 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
7957 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
7959 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
7960 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
7962 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
7963 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
7964 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
7965 switch (tests
[t
].bpp
)
7968 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
7969 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
7970 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
7971 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
7975 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
7976 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
7977 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
7978 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
7981 hr
= IDirectDrawSurface_Unlock(dst
, 0);
7982 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
7986 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
7987 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
7989 if (data
[3] == tests
[t
].clear
)
7991 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
7992 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
7993 * even when a different surface is used. The blit itself doesn't draw anything,
7994 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
7995 * never be masked out by the key.
7997 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
7998 * test is disabled entirely.
8000 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
8001 * terrible on WARP. */
8002 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
8003 IDirectDrawSurface_Release(texture
);
8004 IDirectDrawSurface_Release(src
);
8005 IDirectDrawSurface_Release(dst
);
8010 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
8011 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
8013 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
8014 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
8016 if (c
== tests
[t
].max
)
8017 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
8018 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
8020 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
8021 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
8023 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8024 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
8026 hr
= IDirect3DDevice_BeginScene(device
);
8027 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8028 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
8029 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8030 hr
= IDirect3DDevice_EndScene(device
);
8031 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8033 color
= get_surface_color(rt
, 80, 240);
8035 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
8036 "Got unexpected color 0x%08x, format %s, c=%u.\n",
8037 color
, tests
[t
].name
, c
);
8039 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
8040 "Got unexpected color 0x%08x, format %s, c=%u.\n",
8041 color
, tests
[t
].name
, c
);
8043 color
= get_surface_color(rt
, 240, 240);
8044 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
8045 "Got unexpected color 0x%08x, format %s, c=%u.\n",
8046 color
, tests
[t
].name
, c
);
8048 color
= get_surface_color(rt
, 400, 240);
8049 if (c
== tests
[t
].max
)
8050 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
8051 "Got unexpected color 0x%08x, format %s, c=%u.\n",
8052 color
, tests
[t
].name
, c
);
8054 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
8055 "Got unexpected color 0x%08x, format %s, c=%u.\n",
8056 color
, tests
[t
].name
, c
);
8058 IDirectDrawSurface_Release(texture
);
8060 IDirectDrawSurface_Release(src
);
8061 IDirectDrawSurface_Release(dst
);
8065 destroy_viewport(device
, viewport
);
8066 destroy_material(green
);
8067 IDirectDrawSurface_Release(rt
);
8068 IDirect3DExecuteBuffer_Release(execute_buffer
);
8069 IDirect3DDevice_Release(device
);
8070 refcount
= IDirectDraw_Release(ddraw
);
8071 ok(refcount
== 0, "Ddraw object not properly released, refcount %u.\n", refcount
);
8072 DestroyWindow(window
);
8075 static void test_range_colorkey(void)
8080 IDirectDrawSurface
*surface
;
8081 DDSURFACEDESC surface_desc
;
8085 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8086 0, 0, 640, 480, 0, 0, 0, 0);
8087 ddraw
= create_ddraw();
8088 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8089 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8090 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8092 memset(&surface_desc
, 0, sizeof(surface_desc
));
8093 surface_desc
.dwSize
= sizeof(surface_desc
);
8094 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
8095 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8096 surface_desc
.dwWidth
= 1;
8097 surface_desc
.dwHeight
= 1;
8098 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8099 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8100 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8101 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8102 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8103 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00000000;
8105 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
8106 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
8107 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
8108 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8109 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
8111 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
8112 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
8113 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8114 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
8116 /* Same for DDSCAPS_OFFSCREENPLAIN. */
8117 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8118 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
8119 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
8120 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8121 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
8123 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
8124 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
8125 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8126 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
8128 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
8129 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
8130 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8131 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8133 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
8134 ckey
.dwColorSpaceLowValue
= 0x00000000;
8135 ckey
.dwColorSpaceHighValue
= 0x00000001;
8136 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
8137 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
8139 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
8140 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
8141 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
8142 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
8144 ckey
.dwColorSpaceLowValue
= 0x00000001;
8145 ckey
.dwColorSpaceHighValue
= 0x00000000;
8146 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
8147 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
8149 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
8150 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
8151 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
8152 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
8154 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
8155 ckey
.dwColorSpaceLowValue
= 0x00000000;
8156 ckey
.dwColorSpaceHighValue
= 0x00000000;
8157 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
8158 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
8160 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
8161 ckey
.dwColorSpaceLowValue
= 0x00000001;
8162 ckey
.dwColorSpaceHighValue
= 0x00000000;
8163 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
8164 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
8165 ckey
.dwColorSpaceLowValue
= 0x00000000;
8166 ckey
.dwColorSpaceHighValue
= 0x00000001;
8167 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
8168 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
8169 /* Range destination keys don't work either. */
8170 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
8171 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
8173 /* Just to show it's not because of A, R, and G having equal values. */
8174 ckey
.dwColorSpaceLowValue
= 0x00000000;
8175 ckey
.dwColorSpaceHighValue
= 0x01010101;
8176 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
8177 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
8179 /* None of these operations modified the key. */
8180 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
8181 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
8182 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
8183 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
8185 IDirectDrawSurface_Release(surface
),
8186 refcount
= IDirectDraw_Release(ddraw
);
8187 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8188 DestroyWindow(window
);
8191 static void test_shademode(void)
8193 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8194 IDirect3DExecuteBuffer
*execute_buffer
;
8195 D3DEXECUTEBUFFERDESC exec_desc
;
8196 IDirect3DMaterial
*background
;
8197 IDirect3DViewport
*viewport
;
8198 IDirect3DDevice
*device
;
8199 IDirectDrawSurface
*rt
;
8200 const D3DLVERTEX
*quad
;
8201 DWORD color0
, color1
;
8202 UINT i
, inst_length
;
8208 static const D3DLVERTEX quad_strip
[] =
8210 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
8211 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
8212 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
8213 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
8217 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
8218 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
8219 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
8220 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
8226 DWORD color0
, color1
;
8230 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
8231 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
8232 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
8233 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
8234 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x000000ff, 0x0000ff00},
8235 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
8238 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8239 0, 0, 640, 480, 0, 0, 0, 0);
8240 ddraw
= create_ddraw();
8241 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8242 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8244 skip("Failed to create a 3D device, skipping test.\n");
8245 IDirectDraw_Release(ddraw
);
8246 DestroyWindow(window
);
8250 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
8251 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
8253 background
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
8254 viewport
= create_viewport(device
, 0, 0, 640, 480);
8255 viewport_set_background(device
, viewport
, background
);
8257 memset(&exec_desc
, 0, sizeof(exec_desc
));
8258 exec_desc
.dwSize
= sizeof(exec_desc
);
8259 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
8260 exec_desc
.dwBufferSize
= 1024;
8261 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
8263 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
8264 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
8266 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8267 * the color fixups we have to do for FLAT shading will be dependent on that. */
8269 for (i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); ++i
)
8271 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8272 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8274 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
8275 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
8277 quad
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? quad_strip
: quad_list
;
8278 memcpy(exec_desc
.lpData
, quad
, sizeof(quad_strip
));
8279 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad_strip
);
8280 emit_set_rs(&ptr
, D3DRENDERSTATE_CLIPPING
, FALSE
);
8281 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
8282 emit_set_rs(&ptr
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
8283 emit_set_rs(&ptr
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
8284 emit_set_rs(&ptr
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
8286 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
8287 if (tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
)
8288 emit_tquad(&ptr
, 0);
8290 emit_tquad_tlist(&ptr
, 0);
8292 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
8293 inst_length
-= sizeof(quad_strip
);
8295 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
8296 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
8298 hr
= IDirect3DDevice_BeginScene(device
);
8299 set_execute_data(execute_buffer
, 4, sizeof(quad_strip
), inst_length
);
8300 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
8301 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
8302 hr
= IDirect3DDevice_EndScene(device
);
8303 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8305 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
8306 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
8308 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8309 * each triangle. This requires EXT_provoking_vertex or similar
8310 * functionality being available. */
8311 /* PHONG should be the same as GOURAUD, since no hardware implements
8313 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8314 i
, color0
, tests
[i
].color0
);
8315 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8316 i
, color1
, tests
[i
].color1
);
8319 IDirect3DExecuteBuffer_Release(execute_buffer
);
8320 destroy_viewport(device
, viewport
);
8321 destroy_material(background
);
8322 IDirectDrawSurface_Release(rt
);
8323 refcount
= IDirect3DDevice_Release(device
);
8324 ok(!refcount
, "Device has %u references left.\n", refcount
);
8325 IDirectDraw_Release(ddraw
);
8326 DestroyWindow(window
);
8329 static void test_lockrect_invalid(void)
8333 IDirectDrawSurface
*surface
;
8336 DDSURFACEDESC surface_desc
;
8338 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
8339 static RECT valid
[] =
8347 static RECT invalid
[] =
8349 {68, 60, 60, 68}, /* left > right */
8350 {60, 68, 68, 60}, /* top > bottom */
8351 {-8, 60, 0, 68}, /* left < surface */
8352 {60, -8, 68, 0}, /* top < surface */
8353 {-16, 60, -8, 68}, /* right < surface */
8354 {60, -16, 68, -8}, /* bottom < surface */
8355 {60, 60, 136, 68}, /* right > surface */
8356 {60, 60, 68, 136}, /* bottom > surface */
8357 {136, 60, 144, 68}, /* left > surface */
8358 {60, 136, 68, 144}, /* top > surface */
8368 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, "sysmem offscreenplain", DDERR_INVALIDPARAMS
},
8369 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, "vidmem offscreenplain", DDERR_INVALIDPARAMS
},
8370 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "sysmem texture", DDERR_INVALIDPARAMS
},
8371 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "vidmem texture", DDERR_INVALIDPARAMS
},
8374 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8375 0, 0, 640, 480, 0, 0, 0, 0);
8376 ddraw
= create_ddraw();
8377 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8378 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8379 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8381 memset(&hal_caps
, 0, sizeof(hal_caps
));
8382 hal_caps
.dwSize
= sizeof(hal_caps
);
8383 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
8384 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
8385 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
8387 skip("Required surface types not supported, skipping test.\n");
8391 for (r
= 0; r
< sizeof(resources
) / sizeof(*resources
); ++r
)
8393 memset(&surface_desc
, 0, sizeof(surface_desc
));
8394 surface_desc
.dwSize
= sizeof(surface_desc
);
8395 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8396 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
8397 surface_desc
.dwWidth
= 128;
8398 surface_desc
.dwHeight
= 128;
8399 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
8400 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8401 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8402 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xff0000;
8403 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x00ff00;
8404 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x0000ff;
8406 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8407 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
8409 hr
= IDirectDrawSurface_Lock(surface
, NULL
, NULL
, DDLOCK_WAIT
, NULL
);
8410 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, resources
[r
].name
);
8412 for (i
= 0; i
< sizeof(valid
) / sizeof(*valid
); ++i
)
8414 RECT
*rect
= &valid
[i
];
8416 memset(&surface_desc
, 0, sizeof(surface_desc
));
8417 surface_desc
.dwSize
= sizeof(surface_desc
);
8419 hr
= IDirectDrawSurface_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
8420 ok(SUCCEEDED(hr
), "Lock failed (%#x) for rect %s, type %s.\n",
8421 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
8423 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8424 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
8427 for (i
= 0; i
< sizeof(invalid
) / sizeof(*invalid
); ++i
)
8429 RECT
*rect
= &invalid
[i
];
8431 memset(&surface_desc
, 1, sizeof(surface_desc
));
8432 surface_desc
.dwSize
= sizeof(surface_desc
);
8434 hr
= IDirectDrawSurface_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
8435 ok(hr
== resources
[r
].hr
, "Lock returned %#x for rect %s, type %s.\n",
8436 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
8439 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8440 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
8443 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
8446 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
8447 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#x, type %s.\n",
8448 hr
, resources
[r
].name
);
8449 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
8450 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#x, type %s.\n",
8451 hr
, resources
[r
].name
);
8452 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8453 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
8455 hr
= IDirectDrawSurface_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
8456 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#x).\n", wine_dbgstr_rect(&valid
[0]), hr
);
8457 hr
= IDirectDrawSurface_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
8458 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#x).\n",
8459 wine_dbgstr_rect(&valid
[0]), hr
);
8461 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
8462 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
8464 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8465 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
8467 IDirectDrawSurface_Release(surface
);
8471 IDirectDraw_Release(ddraw
);
8472 DestroyWindow(window
);
8475 static void test_yv12_overlay(void)
8477 IDirectDrawSurface
*src_surface
, *dst_surface
;
8478 RECT rect
= {13, 17, 14, 18};
8479 unsigned int offset
, y
;
8480 unsigned char *base
;
8486 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8487 0, 0, 640, 480, 0, 0, 0, 0);
8488 ddraw
= create_ddraw();
8489 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8490 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8491 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8493 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
8495 skip("Failed to create a YV12 overlay, skipping test.\n");
8499 memset(&desc
, 0, sizeof(desc
));
8500 desc
.dwSize
= sizeof(desc
);
8501 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
8502 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
8504 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
8505 "Got unexpected flags %#x.\n", desc
.dwFlags
);
8506 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
8507 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
8508 "Got unexpected caps %#x.\n", desc
.ddsCaps
.dwCaps
);
8509 ok(desc
.dwWidth
== 256, "Got unexpected width %u.\n", desc
.dwWidth
);
8510 ok(desc
.dwHeight
== 256, "Got unexpected height %u.\n", desc
.dwHeight
);
8511 /* The overlay pitch seems to have 256 byte alignment. */
8512 ok(!(U1(desc
).lPitch
& 0xff), "Got unexpected pitch %u.\n", U1(desc
).lPitch
);
8514 /* Fill the surface with some data for the blit test. */
8515 base
= desc
.lpSurface
;
8517 for (y
= 0; y
< desc
.dwHeight
; ++y
)
8519 memset(base
+ U1(desc
).lPitch
* y
, 0x10, desc
.dwWidth
);
8522 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
8524 memset(base
+ U1(desc
).lPitch
* y
, 0x20, desc
.dwWidth
);
8527 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
8529 memset(base
+ U1(desc
).lPitch
* y
, 0x30, desc
.dwWidth
);
8532 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
8533 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
8535 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
8536 * other block-based formats like DXT the entire Y channel is stored in
8537 * one big chunk of memory, followed by the chroma channels. So partial
8538 * locks do not really make sense. Show that they are allowed nevertheless
8539 * and the offset points into the luminance data. */
8540 hr
= IDirectDrawSurface_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
8541 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
8542 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
8543 ok(offset
== rect
.top
* U1(desc
).lPitch
+ rect
.left
, "Got unexpected offset %u, expected %u.\n",
8544 offset
, rect
.top
* U1(desc
).lPitch
+ rect
.left
);
8545 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
8546 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
8548 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
8550 /* Windows XP with a Radeon X1600 GPU refuses to create a second
8551 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
8552 skip("Failed to create a second YV12 surface, skipping blit test.\n");
8553 IDirectDrawSurface_Release(src_surface
);
8557 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
8558 /* VMware rejects YV12 blits. This behavior has not been seen on real
8559 * hardware yet, so mark it broken. */
8560 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#x.\n", hr
);
8564 memset(&desc
, 0, sizeof(desc
));
8565 desc
.dwSize
= sizeof(desc
);
8566 hr
= IDirectDrawSurface_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
8567 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
8569 base
= desc
.lpSurface
;
8570 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
8571 base
+= desc
.dwHeight
* U1(desc
).lPitch
;
8572 todo_wine
ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
8573 base
+= desc
.dwHeight
/ 4 * U1(desc
).lPitch
;
8574 todo_wine
ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
8576 hr
= IDirectDrawSurface_Unlock(dst_surface
, NULL
);
8577 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
8580 IDirectDrawSurface_Release(dst_surface
);
8581 IDirectDrawSurface_Release(src_surface
);
8583 IDirectDraw_Release(ddraw
);
8584 DestroyWindow(window
);
8587 static BOOL
dwm_enabled(void)
8591 if (!strcmp(winetest_platform
, "wine"))
8593 if (!pDwmIsCompositionEnabled
)
8595 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
8600 static void test_offscreen_overlay(void)
8602 IDirectDrawSurface
*overlay
, *offscreen
, *primary
;
8603 DDSURFACEDESC surface_desc
;
8609 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8610 0, 0, 640, 480, 0, 0, 0, 0);
8611 ddraw
= create_ddraw();
8612 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8613 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8614 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8616 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
8618 skip("Failed to create a UYVY overlay, skipping test.\n");
8622 memset(&surface_desc
, 0, sizeof(surface_desc
));
8623 surface_desc
.dwSize
= sizeof(surface_desc
);
8624 surface_desc
.dwFlags
= DDSD_CAPS
;
8625 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8626 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
8627 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
8629 /* On Windows 7, and probably Vista, UpdateOverlay() will return
8630 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
8631 * surface prevents this by disabling the dwm. */
8632 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
8633 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8634 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
8635 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8637 /* Try to overlay a NULL surface. */
8638 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
8639 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8640 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
8641 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8643 /* Try to overlay an offscreen surface. */
8644 memset(&surface_desc
, 0, sizeof(surface_desc
));
8645 surface_desc
.dwSize
= sizeof(surface_desc
);
8646 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8647 surface_desc
.dwWidth
= 64;
8648 surface_desc
.dwHeight
= 64;
8649 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8650 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
8651 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8652 surface_desc
.ddpfPixelFormat
.dwFourCC
= 0;
8653 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
8654 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
8655 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
8656 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
8657 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
8658 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
8660 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
8661 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled()),
8662 "Failed to update overlay, hr %#x.\n", hr
);
8664 /* Try to overlay the primary with a non-overlay surface. */
8665 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
8666 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
8667 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
8668 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
8670 IDirectDrawSurface_Release(offscreen
);
8671 IDirectDrawSurface_Release(primary
);
8672 IDirectDrawSurface_Release(overlay
);
8674 IDirectDraw_Release(ddraw
);
8675 DestroyWindow(window
);
8678 static void test_overlay_rect(void)
8680 IDirectDrawSurface
*overlay
, *primary
= NULL
;
8681 DDSURFACEDESC surface_desc
;
8682 RECT rect
= {0, 0, 64, 64};
8689 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8690 0, 0, 640, 480, 0, 0, 0, 0);
8691 ddraw
= create_ddraw();
8692 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8693 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8694 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8696 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
8698 skip("Failed to create a UYVY overlay, skipping test.\n");
8702 memset(&surface_desc
, 0, sizeof(surface_desc
));
8703 surface_desc
.dwSize
= sizeof(surface_desc
);
8704 surface_desc
.dwFlags
= DDSD_CAPS
;
8705 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8706 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
8707 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
8709 /* On Windows 7, and probably Vista, UpdateOverlay() will return
8710 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
8711 * surface prevents this by disabling the dwm. */
8712 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
8713 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8714 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
8715 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8717 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
8720 win_skip("Cannot disable DWM, skipping overlay test.\n");
8724 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
8725 * used. This is not true in Windows Vista and earlier, but changed in
8727 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
8728 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
8729 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
8730 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
8731 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
8732 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8734 /* Show that the overlay position is the (top, left) coordinate of the
8735 * destination rectangle. */
8736 OffsetRect(&rect
, 32, 16);
8737 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
8738 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
8739 pos_x
= -1; pos_y
= -1;
8740 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
8741 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
8742 ok(pos_x
== rect
.left
, "Got unexpected pos_x %d, expected %d.\n", pos_x
, rect
.left
);
8743 ok(pos_y
== rect
.top
, "Got unexpected pos_y %d, expected %d.\n", pos_y
, rect
.top
);
8745 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
8746 * seen that the overlay overlays the whole primary(==screen). */
8747 hr2
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
8748 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#x.\n", hr2
);
8749 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
8750 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
8753 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
8754 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
8758 ok(pos_x
== 32, "Got unexpected pos_x %d.\n", pos_x
);
8759 ok(pos_y
== 16, "Got unexpected pos_y %d.\n", pos_y
);
8762 /* The position cannot be retrieved when the overlay is not shown. */
8763 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
8764 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
8765 pos_x
= -1; pos_y
= -1;
8766 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
8767 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#x.\n", hr
);
8768 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
8769 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
8771 IDirectDrawSurface_Release(overlay
);
8774 IDirectDrawSurface_Release(primary
);
8775 IDirectDraw_Release(ddraw
);
8776 DestroyWindow(window
);
8779 static void test_blt(void)
8781 IDirectDrawSurface
*surface
, *rt
;
8782 DDSURFACEDESC surface_desc
;
8783 IDirect3DDevice
*device
;
8798 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
8799 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
8800 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
8801 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
8802 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
8803 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
8804 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
8805 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
8806 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
8807 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
8810 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8811 0, 0, 640, 480, 0, 0, 0, 0);
8812 ddraw
= create_ddraw();
8813 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8814 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8816 skip("Failed to create a 3D device, skipping test.\n");
8817 IDirectDraw_Release(ddraw
);
8818 DestroyWindow(window
);
8822 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
8823 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
8825 memset(&surface_desc
, 0, sizeof(surface_desc
));
8826 surface_desc
.dwSize
= sizeof(surface_desc
);
8827 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
8828 surface_desc
.dwWidth
= 640;
8829 surface_desc
.dwHeight
= 480;
8830 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8831 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8832 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8834 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
8835 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
8837 hr
= IDirectDrawSurface_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
8838 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
8840 for (i
= 0; i
< sizeof(test_data
) / sizeof(*test_data
); ++i
)
8842 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
8843 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
8844 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
8846 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
8847 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
8848 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
8851 IDirectDrawSurface_Release(surface
);
8852 IDirectDrawSurface_Release(rt
);
8853 refcount
= IDirect3DDevice_Release(device
);
8854 ok(!refcount
, "Device has %u references left.\n", refcount
);
8855 IDirectDraw_Release(ddraw
);
8856 DestroyWindow(window
);
8859 static void test_getdc(void)
8861 IDirectDrawSurface
*surface
, *surface2
, *tmp
;
8862 DDSURFACEDESC surface_desc
, map_desc
;
8863 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
8873 DDPIXELFORMAT format
;
8874 BOOL getdc_supported
;
8879 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
8880 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
8881 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
8882 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
8883 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
8884 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
8885 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
8886 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
8887 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
8888 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
8889 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
8890 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
8891 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
8892 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
8893 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
8894 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
8895 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
8896 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
8897 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
8898 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
8899 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
8900 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
8901 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
8902 * This is not implemented in wine yet, so disable the test for now.
8903 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
8904 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
8905 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
8907 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
8908 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
8909 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
8910 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
8911 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
8912 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
8913 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
8914 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
8915 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
8916 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
8917 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
8918 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
8919 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
8920 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
8923 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8924 0, 0, 640, 480, 0, 0, 0, 0);
8925 ddraw
= create_ddraw();
8926 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8927 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8928 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8930 for (i
= 0; i
< (sizeof(test_data
) / sizeof(*test_data
)); ++i
)
8932 memset(&surface_desc
, 0, sizeof(surface_desc
));
8933 surface_desc
.dwSize
= sizeof(surface_desc
);
8934 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8935 surface_desc
.dwWidth
= 64;
8936 surface_desc
.dwHeight
= 64;
8937 surface_desc
.ddpfPixelFormat
= test_data
[i
].format
;
8938 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8940 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
8942 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8943 if (FAILED(hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
8945 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", test_data
[i
].name
, hr
);
8950 dc
= (void *)0x1234;
8951 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8952 if (test_data
[i
].getdc_supported
)
8953 ok(SUCCEEDED(hr
) || (test_data
[i
].alt_result
&& hr
== test_data
[i
].alt_result
),
8954 "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
8956 ok(FAILED(hr
), "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
8960 unsigned int width_bytes
;
8966 type
= GetObjectType(dc
);
8967 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
8968 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
8969 type
= GetObjectType(bitmap
);
8970 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
8972 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
8973 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
8974 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
8975 dib
.dsBm
.bmType
, test_data
[i
].name
);
8976 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
8977 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
8978 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
8979 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
8980 width_bytes
= ((dib
.dsBm
.bmWidth
* U1(test_data
[i
].format
).dwRGBBitCount
+ 31) >> 3) & ~3;
8981 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
8982 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
8983 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
8984 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
8985 ok(dib
.dsBm
.bmBitsPixel
== U1(test_data
[i
].format
).dwRGBBitCount
,
8986 "Got unexpected bit count %d for format %s.\n",
8987 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
8988 ok(!!dib
.dsBm
.bmBits
, "Got unexpected bits %p for format %s.\n",
8989 dib
.dsBm
.bmBits
, test_data
[i
].name
);
8991 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %u for format %s.\n",
8992 dib
.dsBmih
.biSize
, test_data
[i
].name
);
8993 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
8994 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
8995 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
8996 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
8997 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
8998 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
8999 ok(dib
.dsBmih
.biBitCount
== U1(test_data
[i
].format
).dwRGBBitCount
,
9000 "Got unexpected bit count %u for format %s.\n",
9001 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
9002 ok(dib
.dsBmih
.biCompression
== (U1(test_data
[i
].format
).dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
9003 || broken(U1(test_data
[i
].format
).dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
9004 "Got unexpected compression %#x for format %s.\n",
9005 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
9006 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %u for format %s.\n",
9007 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
9008 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %d for format %s.\n",
9009 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
9010 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %d for format %s.\n",
9011 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
9012 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %u for format %s.\n",
9013 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
9014 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %u for format %s.\n",
9015 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
9017 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
9019 ok((dib
.dsBitfields
[0] == U2(test_data
[i
].format
).dwRBitMask
9020 && dib
.dsBitfields
[1] == U3(test_data
[i
].format
).dwGBitMask
9021 && dib
.dsBitfields
[2] == U4(test_data
[i
].format
).dwBBitMask
)
9022 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
9023 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
9024 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
9028 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
9029 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
9030 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
9032 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
9033 ok(!dib
.dsOffset
, "Got unexpected offset %u for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
9035 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
9036 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9040 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
9043 IDirectDrawSurface_Release(surface
);
9048 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
9049 if (FAILED(hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
9051 skip("Failed to create mip-mapped texture for format %s (hr %#x), skipping tests.\n",
9052 test_data
[i
].name
, hr
);
9056 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
9057 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9058 hr
= IDirectDrawSurface_GetAttachedSurface(tmp
, &caps
, &surface2
);
9059 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9060 IDirectDrawSurface_Release(tmp
);
9062 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
9063 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9064 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
9065 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9066 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
9067 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9068 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
9069 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9071 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
9072 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9073 dc2
= (void *)0x1234;
9074 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
9075 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
9076 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
9077 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
9078 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9079 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
9080 ok(hr
== DDERR_NODC
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
9082 map_desc
.dwSize
= sizeof(map_desc
);
9083 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
9084 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9085 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
9086 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
9087 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9088 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9089 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9090 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
9092 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
9093 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9094 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
9095 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
9096 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
9097 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9099 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
9100 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9101 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
9102 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9103 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
9104 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9105 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9106 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9108 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
9109 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9110 hr
= IDirectDrawSurface_GetDC(surface2
, &dc2
);
9111 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9112 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc2
);
9113 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9114 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
9115 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9117 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
9118 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9119 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
9120 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9121 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc2
);
9122 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9123 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
9124 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9126 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
9127 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9128 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
9129 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9130 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
9131 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9132 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9133 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9135 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
9136 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9137 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
9138 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9139 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
9140 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9141 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9142 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9144 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
9145 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9146 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
9147 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9148 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
9149 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9150 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
9151 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9153 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
9154 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9155 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
9156 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9157 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
9158 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9159 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
9160 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9162 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
9163 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9164 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
9165 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9166 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9167 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9168 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
9169 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9171 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9172 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
9173 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
9174 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9175 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9176 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
9177 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
9178 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9179 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9180 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
9182 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
9183 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
9184 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
9185 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9186 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
9187 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
9188 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
9189 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
9190 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
9191 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
9193 IDirectDrawSurface_Release(surface2
);
9194 IDirectDrawSurface_Release(surface
);
9197 IDirectDraw_Release(ddraw
);
9198 DestroyWindow(window
);
9201 /* TransformVertices always writes 32 bytes regardless of the input / output stride.
9202 * The stride is honored for navigating to the next vertex. 3 floats input position
9203 * are read, and 16 bytes extra vertex data are copied around. */
9204 struct transform_input
9206 float x
, y
, z
, unused1
; /* Position data, transformed. */
9207 DWORD v1
, v2
, v3
, v4
; /* Extra data, e.g. color and texture coords, copied. */
9211 struct transform_output
9214 DWORD v1
, v2
, v3
, v4
;
9215 DWORD unused3
, unused4
;
9218 static void test_transform_vertices(void)
9220 IDirect3DDevice
*device
;
9221 IDirectDrawSurface
*rt
;
9227 IDirect3DViewport
*viewport
;
9228 IDirect3DExecuteBuffer
*execute_buffer
;
9229 IDirect3DMaterial
*background
;
9230 D3DEXECUTEBUFFERDESC exec_desc
;
9233 D3DMATRIXHANDLE world_handle
, view_handle
, proj_handle
;
9234 static struct transform_input position_tests
[] =
9236 { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
9237 { 1.0f
, 1.0f
, 1.0f
, 8.0f
, 6, 7, 8, 9, 10},
9238 {-1.0f
, -1.0f
, -1.0f
, 4.0f
, 11, 12, 13, 14, 15},
9239 { 0.5f
, 0.5f
, 0.5f
, 2.0f
, 16, 17, 18, 19, 20},
9240 {-0.5f
, -0.5f
, -0.5f
, 1.0f
, ~1U, ~2U, ~3U, ~4U, ~5U},
9241 {-0.5f
, -0.5f
, 0.0f
, 0.0f
, ~6U, ~7U, ~8U, ~9U, ~0U},
9243 static struct transform_input cliptest
[] =
9245 { 25.59f
, 25.59f
, 1.0f
, 0.0f
, 1, 2, 3, 4, 5},
9246 { 25.61f
, 25.61f
, 1.01f
, 0.0f
, 1, 2, 3, 4, 5},
9247 {-25.59f
, -25.59f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
9248 {-25.61f
, -25.61f
, -0.01f
, 0.0f
, 1, 2, 3, 4, 5},
9250 static struct transform_input offscreentest
[] =
9252 {128.1f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
9254 struct transform_output out
[ARRAY_SIZE(position_tests
)];
9255 D3DHVERTEX out_h
[ARRAY_SIZE(position_tests
)];
9256 D3DTRANSFORMDATA transformdata
;
9257 static const D3DVIEWPORT vp_template
=
9259 sizeof(vp_template
), 0, 0, 256, 256, 5.0f
, 5.0f
, 256.0f
, 256.0f
, -25.0f
, 60.0f
9261 D3DVIEWPORT vp_data
=
9263 sizeof(vp_data
), 0, 0, 256, 256, 1.0f
, 1.0f
, 256.0f
, 256.0f
, 0.0f
, 1.0f
9267 static D3DMATRIX mat_scale
=
9269 2.0f
, 0.0f
, 0.0f
, 0.0f
,
9270 0.0f
, 2.0f
, 0.0f
, 0.0f
,
9271 0.0f
, 0.0f
, 2.0f
, 0.0f
,
9272 0.0f
, 0.0f
, 0.0f
, 1.0f
,
9276 1.0f
, 0.0f
, 0.0f
, 0.0f
,
9277 0.0f
, 1.0f
, 0.0f
, 0.0f
,
9278 0.0f
, 0.0f
, 1.0f
, 0.0f
,
9279 1.0f
, 0.0f
, 0.0f
, 1.0f
,
9283 1.0f
, 0.0f
, 0.0f
, 0.0f
,
9284 0.0f
, 1.0f
, 0.0f
, 0.0f
,
9285 0.0f
, 0.0f
, 1.0f
, 0.0f
,
9286 0.0f
, 1.0f
, 0.0f
, 1.0f
,
9288 static const D3DLVERTEX quad
[] =
9290 {{-0.75f
},{-0.5f
}, {0.0f
}, 0, {0xffff0000}},
9291 {{-0.75f
},{ 0.25f
}, {0.0f
}, 0, {0xffff0000}},
9292 {{ 0.5f
}, {-0.5f
}, {0.0f
}, 0, {0xffff0000}},
9293 {{ 0.5f
}, { 0.25f
}, {0.0f
}, 0, {0xffff0000}},
9295 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9298 for (i
= 0; i
< ARRAY_SIZE(out
); ++i
)
9300 out
[i
].unused3
= 0xdeadbeef;
9301 out
[i
].unused4
= 0xcafecafe;
9304 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9305 0, 0, 640, 480, 0, 0, 0, 0);
9306 ddraw
= create_ddraw();
9307 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9308 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9310 skip("Failed to create a 3D device, skipping test.\n");
9311 IDirectDraw_Release(ddraw
);
9312 DestroyWindow(window
);
9316 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
9317 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
9319 viewport
= create_viewport(device
, 0, 0, 256, 256);
9320 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
9321 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
9323 memset(&transformdata
, 0, sizeof(transformdata
));
9324 transformdata
.dwSize
= sizeof(transformdata
);
9325 transformdata
.lpIn
= position_tests
;
9326 transformdata
.dwInSize
= sizeof(position_tests
[0]);
9327 transformdata
.lpOut
= out
;
9328 transformdata
.dwOutSize
= sizeof(out
[0]);
9329 transformdata
.lpHOut
= NULL
;
9331 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
9332 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
9333 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9334 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
9336 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
9338 static const struct vec4 cmp
[] =
9340 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {129.0f
, 127.0f
, 1.0f
, 1.0f
}, {127.0f
, 129.0f
, -1.0f
, 1.0f
},
9341 {128.5f
, 127.5f
, 0.5f
, 1.0f
}, {127.5f
, 128.5f
, -0.5f
, 1.0f
}, {127.5f
, 128.5f
, 0.0f
, 1.0f
}
9344 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
9345 "Vertex %u differs. Got %f %f %f %f.\n", i
,
9346 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
9347 ok(out
[i
].v1
== position_tests
[i
].v1
&& out
[i
].v2
== position_tests
[i
].v2
9348 && out
[i
].v3
== position_tests
[i
].v3
&& out
[i
].v4
== position_tests
[i
].v4
,
9349 "Vertex %u payload is %u %u %u %u.\n", i
, out
[i
].v1
, out
[i
].v2
, out
[i
].v3
, out
[i
].v4
);
9350 ok(out
[i
].unused3
== 0xdeadbeef && out
[i
].unused4
== 0xcafecafe,
9351 "Vertex %u unused data is %#x, %#x.\n", i
, out
[i
].unused3
, out
[i
].unused4
);
9354 vp_data
= vp_template
;
9355 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
9356 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
9357 offscreen
= 0xdeadbeef;
9358 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
9359 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
9360 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9361 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
9363 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
9365 static const struct vec4 cmp
[] =
9367 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {133.0f
, 123.0f
, 1.0f
, 1.0f
}, {123.0f
, 133.0f
, -1.0f
, 1.0f
},
9368 {130.5f
, 125.5f
, 0.5f
, 1.0f
}, {125.5f
, 130.5f
, -0.5f
, 1.0f
}, {125.5f
, 130.5f
, 0.0f
, 1.0f
}
9370 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
9371 "Vertex %u differs. Got %f %f %f %f.\n", i
,
9372 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
9377 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
9378 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
9379 offscreen
= 0xdeadbeef;
9380 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
9381 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
9382 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9383 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
9384 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
9386 static const struct vec4 cmp
[] =
9388 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, {133.0f
, 153.0f
, -1.0f
, 1.0f
},
9389 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, {135.5f
, 150.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
9391 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
9392 "Vertex %u differs. Got %f %f %f %f.\n", i
,
9393 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
9396 transformdata
.lpHOut
= out_h
;
9397 offscreen
= 0xdeadbeef;
9398 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
9399 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9400 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9401 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
9402 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
9404 static const D3DHVERTEX cmp_h
[] =
9406 {0, { 0.0f
}, { 0.0f
}, { 0.0f
}}, {0, { 1.0f
}, { 1.0f
}, {1.0f
}},
9407 {D3DCLIP_FRONT
, {-1.0f
}, {-1.0f
}, {-1.0f
}}, {0, { 0.5f
}, { 0.5f
}, {0.5f
}},
9408 {D3DCLIP_FRONT
, {-0.5f
}, {-0.5f
}, {-0.5f
}}, {0, {-0.5f
}, {-0.5f
}, {0.0f
}}
9410 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
9411 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
9412 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
9413 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
9414 "HVertex %u differs. Got %#x %f %f %f.\n", i
,
9415 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
9417 /* No scheme has been found behind those return values. It seems to be
9418 * whatever data windows has when throwing the vertex away. Modify the
9419 * input test vertices to test this more. Depending on the input data
9420 * it can happen that the z coord gets written into y, or similar things. */
9423 static const struct vec4 cmp
[] =
9425 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, { -1.0f
, -1.0f
, 0.5f
, 1.0f
},
9426 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, { -0.5f
, -0.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
9428 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
9429 "Vertex %u differs. Got %f %f %f %f.\n", i
,
9430 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
9434 transformdata
.lpIn
= cliptest
;
9435 transformdata
.dwInSize
= sizeof(cliptest
[0]);
9436 offscreen
= 0xdeadbeef;
9437 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
9438 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9439 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9440 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
9441 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
9443 static const DWORD flags
[] =
9446 D3DCLIP_RIGHT
| D3DCLIP_BACK
| D3DCLIP_TOP
,
9448 D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,
9450 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
9453 vp_data
= vp_template
;
9454 vp_data
.dwWidth
= 10;
9455 vp_data
.dwHeight
= 1000;
9456 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
9457 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
9458 offscreen
= 0xdeadbeef;
9459 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
9460 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9461 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9462 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
9463 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
9465 static const DWORD flags
[] =
9468 D3DCLIP_RIGHT
| D3DCLIP_BACK
,
9470 D3DCLIP_LEFT
| D3DCLIP_FRONT
,
9472 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
9475 vp_data
= vp_template
;
9476 vp_data
.dwWidth
= 256;
9477 vp_data
.dwHeight
= 256;
9478 vp_data
.dvScaleX
= 1;
9479 vp_data
.dvScaleY
= 1;
9480 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
9481 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
9482 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
9483 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9484 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9485 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
9486 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
9488 static const DWORD flags
[] =
9495 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
9498 /* Finally try to figure out how the DWORD dwOffscreen works.
9499 * It is a logical AND of the vertices' dwFlags members. */
9500 vp_data
= vp_template
;
9501 vp_data
.dwWidth
= 5;
9502 vp_data
.dwHeight
= 5;
9503 vp_data
.dvScaleX
= 10000.0f
;
9504 vp_data
.dvScaleY
= 10000.0f
;
9505 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
9506 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
9507 transformdata
.lpIn
= cliptest
;
9508 offscreen
= 0xdeadbeef;
9509 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
9510 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
9511 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9512 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
9514 offscreen
= 0xdeadbeef;
9515 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
9516 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9517 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9518 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
9519 offscreen
= 0xdeadbeef;
9520 hr
= IDirect3DViewport_TransformVertices(viewport
, 2,
9521 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9522 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9523 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
9524 hr
= IDirect3DViewport_TransformVertices(viewport
, 3,
9525 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9526 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9527 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
9529 transformdata
.lpIn
= cliptest
+ 1;
9530 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
9531 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9532 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9533 ok(offscreen
== (D3DCLIP_BACK
| D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
9535 transformdata
.lpIn
= cliptest
+ 2;
9536 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
9537 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9538 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9539 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
9540 offscreen
= 0xdeadbeef;
9541 hr
= IDirect3DViewport_TransformVertices(viewport
, 2,
9542 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9543 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9544 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
9546 transformdata
.lpIn
= cliptest
+ 3;
9547 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
9548 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9549 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9550 ok(offscreen
== (D3DCLIP_FRONT
| D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
9552 transformdata
.lpIn
= offscreentest
;
9553 transformdata
.dwInSize
= sizeof(offscreentest
[0]);
9554 vp_data
= vp_template
;
9555 vp_data
.dwWidth
= 257;
9556 vp_data
.dwHeight
= 257;
9557 vp_data
.dvScaleX
= 1.0f
;
9558 vp_data
.dvScaleY
= 1.0f
;
9559 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
9560 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
9561 offscreen
= 0xdeadbeef;
9562 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
9563 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9564 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9565 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
9567 vp_data
.dwWidth
= 256;
9568 vp_data
.dwHeight
= 256;
9569 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
9570 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
9571 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
9572 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9573 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9574 ok(offscreen
== D3DCLIP_RIGHT
, "Offscreen is %x.\n", offscreen
);
9576 /* Test the effect of Matrices.
9578 * Basically the x coordinate ends up as ((x + 1) * 2 + 0) * 5 and
9579 * y as ((y + 0) * 2 + 1) * 5. The 5 comes from dvScaleX/Y, 2 from
9580 * the view matrix and the +1's from the world and projection matrix. */
9583 vp_data
.dwWidth
= 256;
9584 vp_data
.dwHeight
= 256;
9585 vp_data
.dvScaleX
= 5.0f
;
9586 vp_data
.dvScaleY
= 5.0f
;
9587 vp_data
.dvMinZ
= 0.0f
;
9588 vp_data
.dvMaxZ
= 1.0f
;
9589 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
9590 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
9592 hr
= IDirect3DDevice_CreateMatrix(device
, &world_handle
);
9593 ok(hr
== D3D_OK
, "Creating a matrix object failed, hr %#x.\n", hr
);
9594 hr
= IDirect3DDevice_SetMatrix(device
, world_handle
, &mat_translate1
);
9595 ok(hr
== D3D_OK
, "Setting a matrix object failed, hr %#x.\n", hr
);
9597 hr
= IDirect3DDevice_CreateMatrix(device
, &view_handle
);
9598 ok(hr
== D3D_OK
, "Creating a matrix object failed, hr %#x.\n", hr
);
9599 hr
= IDirect3DDevice_SetMatrix(device
, view_handle
, &mat_scale
);
9600 ok(hr
== D3D_OK
, "Setting a matrix object failed, hr %#x.\n", hr
);
9602 hr
= IDirect3DDevice_CreateMatrix(device
, &proj_handle
);
9603 ok(hr
== D3D_OK
, "Creating a matrix object failed, hr %#x.\n", hr
);
9604 hr
= IDirect3DDevice_SetMatrix(device
, proj_handle
, &mat_translate2
);
9605 ok(hr
== D3D_OK
, "Setting a matrix object failed, hr %#x.\n", hr
);
9607 memset(&exec_desc
, 0, sizeof(exec_desc
));
9608 exec_desc
.dwSize
= sizeof(exec_desc
);
9609 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
9610 exec_desc
.dwBufferSize
= 1024;
9611 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
9612 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
9613 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
9615 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
9616 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
9617 ptr
= (BYTE
*)exec_desc
.lpData
;
9618 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_WORLD
, world_handle
);
9619 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_VIEW
, view_handle
);
9620 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_PROJECTION
, proj_handle
);
9622 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
9623 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
9624 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
9626 set_execute_data(execute_buffer
, 0, 0, inst_length
);
9627 hr
= IDirect3DDevice_BeginScene(device
);
9628 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9629 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
9630 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
9631 hr
= IDirect3DDevice_EndScene(device
);
9632 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9634 transformdata
.lpIn
= position_tests
;
9635 transformdata
.dwInSize
= sizeof(position_tests
[0]);
9636 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
9637 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
9638 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9640 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
9642 static const struct vec4 cmp
[] =
9644 {138.0f
, 123.0f
, 0.0f
, 1.0f
}, {148.0f
, 113.0f
, 2.0f
, 1.0f
}, {128.0f
, 133.0f
, -2.0f
, 1.0f
},
9645 {143.0f
, 118.0f
, 1.0f
, 1.0f
}, {133.0f
, 128.0f
, -1.0f
, 1.0f
}, {133.0f
, 128.0f
, 0.0f
, 1.0f
}
9648 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
9649 "Vertex %u differs. Got %f %f %f %f.\n", i
,
9650 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
9653 /* Invalid flags. */
9654 offscreen
= 0xdeadbeef;
9655 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
9656 &transformdata
, 0, &offscreen
);
9657 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
9658 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
9660 /* NULL transform data. */
9661 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
9662 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
9663 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
9664 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
9665 hr
= IDirect3DViewport_TransformVertices(viewport
, 0,
9666 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
9667 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
9668 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
9670 /* NULL transform data and NULL dwOffscreen.
9672 * Valid transform data + NULL dwOffscreen -> crash. */
9673 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
9674 NULL
, D3DTRANSFORM_UNCLIPPED
, NULL
);
9675 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
9678 hr
= IDirect3DViewport_TransformVertices(viewport
, 0,
9679 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
9680 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9681 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
9682 hr
= IDirect3DViewport_TransformVertices(viewport
, 0,
9683 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9684 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9685 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
9687 /* Invalid sizes. */
9688 offscreen
= 0xdeadbeef;
9689 transformdata
.dwSize
= sizeof(transformdata
) - 1;
9690 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
9691 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
9692 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
9693 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
9694 transformdata
.dwSize
= sizeof(transformdata
) + 1;
9695 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
9696 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
9697 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
9698 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
9700 /* NULL lpIn or lpOut -> crash, except when transforming 0 vertices. */
9701 transformdata
.dwSize
= sizeof(transformdata
);
9702 transformdata
.lpIn
= NULL
;
9703 transformdata
.lpOut
= NULL
;
9704 offscreen
= 0xdeadbeef;
9705 hr
= IDirect3DViewport_TransformVertices(viewport
, 0,
9706 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
9707 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
9708 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
9710 /* Test how vertices are transformed by execute buffers. */
9713 vp_data
.dwWidth
= 200;
9714 vp_data
.dwHeight
= 400;
9715 vp_data
.dvScaleX
= 20.0f
;
9716 vp_data
.dvScaleY
= 50.0f
;
9717 vp_data
.dvMinZ
= 0.0f
;
9718 vp_data
.dvMaxZ
= 1.0f
;
9719 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
9720 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
9722 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 0.0f
);
9723 viewport_set_background(device
, viewport
, background
);
9724 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9725 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
9727 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
9728 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
9729 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
9730 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
9731 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
9732 emit_tquad(&ptr
, 0);
9734 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
9735 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
9736 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
9738 set_execute_data(execute_buffer
, 4, sizeof(quad
), inst_length
);
9739 hr
= IDirect3DDevice_BeginScene(device
);
9740 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9741 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
9742 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
9743 hr
= IDirect3DDevice_EndScene(device
);
9744 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9746 color
= get_surface_color(rt
, 128, 143);
9747 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
9748 color
= get_surface_color(rt
, 132, 143);
9749 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
9750 color
= get_surface_color(rt
, 128, 147);
9751 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
9752 color
= get_surface_color(rt
, 132, 147);
9753 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9755 color
= get_surface_color(rt
, 177, 217);
9756 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9757 color
= get_surface_color(rt
, 181, 217);
9758 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
9759 color
= get_surface_color(rt
, 177, 221);
9760 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
9761 color
= get_surface_color(rt
, 181, 221);
9762 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
9764 IDirect3DDevice_DeleteMatrix(device
, world_handle
);
9765 IDirect3DDevice_DeleteMatrix(device
, view_handle
);
9766 IDirect3DDevice_DeleteMatrix(device
, proj_handle
);
9767 IDirect3DExecuteBuffer_Release(execute_buffer
);
9769 IDirectDrawSurface_Release(rt
);
9770 destroy_viewport(device
, viewport
);
9771 IDirect3DMaterial_Release(background
);
9772 refcount
= IDirect3DDevice_Release(device
);
9773 ok(!refcount
, "Device has %u references left.\n", refcount
);
9774 IDirectDraw_Release(ddraw
);
9775 DestroyWindow(window
);
9778 static void test_display_mode_surface_pixel_format(void)
9780 unsigned int width
, height
, bpp
;
9781 IDirectDrawSurface
*surface
;
9782 DDSURFACEDESC surface_desc
;
9788 if (!(ddraw
= create_ddraw()))
9790 skip("Failed to create ddraw.\n");
9794 surface_desc
.dwSize
= sizeof(surface_desc
);
9795 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
9796 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
9797 width
= surface_desc
.dwWidth
;
9798 height
= surface_desc
.dwHeight
;
9800 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9801 0, 0, width
, height
, NULL
, NULL
, NULL
, NULL
);
9802 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9803 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9806 if (SUCCEEDED(IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 16)))
9808 if (SUCCEEDED(IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 24)))
9810 if (SUCCEEDED(IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 32)))
9812 ok(bpp
, "Set display mode failed.\n");
9814 surface_desc
.dwSize
= sizeof(surface_desc
);
9815 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
9816 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
9817 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
9818 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
9819 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
9820 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
9822 memset(&surface_desc
, 0, sizeof(surface_desc
));
9823 surface_desc
.dwSize
= sizeof(surface_desc
);
9824 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
9825 surface_desc
.dwBackBufferCount
= 1;
9826 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_PRIMARYSURFACE
;
9827 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9828 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
9829 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
9830 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9831 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
9832 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
9833 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
9834 surface_desc
.ddpfPixelFormat
.dwFlags
);
9835 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
9836 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
9837 IDirectDrawSurface_Release(surface
);
9839 memset(&surface_desc
, 0, sizeof(surface_desc
));
9840 surface_desc
.dwSize
= sizeof(surface_desc
);
9841 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
9842 surface_desc
.dwWidth
= width
;
9843 surface_desc
.dwHeight
= height
;
9844 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9845 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9846 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
9847 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
9848 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9849 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
9850 surface_desc
.ddpfPixelFormat
.dwFlags
);
9851 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
9852 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
9853 IDirectDrawSurface_Release(surface
);
9855 refcount
= IDirectDraw_Release(ddraw
);
9856 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
9857 DestroyWindow(window
);
9860 static void test_surface_desc_size(void)
9865 DDSURFACEDESC desc1
;
9866 DDSURFACEDESC2 desc2
;
9869 IDirectDrawSurface7
*surface7
;
9870 IDirectDrawSurface
*surface
;
9871 DDSURFACEDESC surface_desc
;
9872 HRESULT expected_hr
, hr
;
9884 {DDSCAPS_OFFSCREENPLAIN
, "offscreenplain"},
9885 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "systemmemory texture"},
9886 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "videomemory texture"},
9888 static const unsigned int desc_sizes
[] =
9890 sizeof(DDSURFACEDESC
),
9891 sizeof(DDSURFACEDESC2
),
9892 sizeof(DDSURFACEDESC
) + 1,
9893 sizeof(DDSURFACEDESC2
) + 1,
9894 2 * sizeof(DDSURFACEDESC
),
9895 2 * sizeof(DDSURFACEDESC2
),
9896 sizeof(DDSURFACEDESC
) - 1,
9897 sizeof(DDSURFACEDESC2
) - 1,
9898 sizeof(DDSURFACEDESC
) / 2,
9899 sizeof(DDSURFACEDESC2
) / 2,
9907 if (!(ddraw
= create_ddraw()))
9909 skip("Failed to create ddraw.\n");
9912 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
9913 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9915 for (i
= 0; i
< sizeof(surface_caps
) / sizeof(*surface_caps
); ++i
)
9917 memset(&surface_desc
, 0, sizeof(surface_desc
));
9918 surface_desc
.dwSize
= sizeof(surface_desc
);
9919 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
9920 surface_desc
.ddsCaps
.dwCaps
= surface_caps
[i
].caps
;
9921 surface_desc
.dwHeight
= 128;
9922 surface_desc
.dwWidth
= 128;
9923 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
9925 skip("Failed to create surface, type %s.\n", surface_caps
[i
].name
);
9928 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface7
, (void **)&surface7
);
9929 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface7, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
9931 /* GetSurfaceDesc() */
9932 for (j
= 0; j
< sizeof(desc_sizes
) / sizeof(*desc_sizes
); ++j
)
9934 memset(&desc
, 0, sizeof(desc
));
9935 desc
.dwSize
= desc_sizes
[j
];
9936 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
9937 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
.desc1
);
9938 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
9939 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
9941 memset(&desc
, 0, sizeof(desc
));
9942 desc
.dwSize
= desc_sizes
[j
];
9943 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC2
) ? DD_OK
: DDERR_INVALIDPARAMS
;
9944 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface7
, &desc
.desc2
);
9945 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
9946 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
9950 for (j
= 0; j
< sizeof(desc_sizes
) / sizeof(*desc_sizes
); ++j
)
9952 const BOOL valid_size
= desc_sizes
[j
] == sizeof(DDSURFACEDESC
)
9953 || desc_sizes
[j
] == sizeof(DDSURFACEDESC2
);
9954 DWORD expected_texture_stage
;
9956 memset(&desc
, 0, sizeof(desc
));
9957 desc
.dwSize
= desc_sizes
[j
];
9958 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
9959 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
9960 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
.desc1
, 0, 0);
9961 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
9962 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
9963 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
9964 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
9965 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
9966 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
9967 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
9970 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
9971 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
9972 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
9973 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
9974 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
9975 todo_wine_if(!expected_texture_stage
)
9976 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
9977 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
9978 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
9979 IDirectDrawSurface_Unlock(surface
, NULL
);
9982 memset(&desc
, 0, sizeof(desc
));
9983 desc
.dwSize
= desc_sizes
[j
];
9984 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
9985 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
9986 hr
= IDirectDrawSurface7_Lock(surface7
, NULL
, &desc
.desc2
, 0, 0);
9987 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
9988 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
9989 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
9990 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
9991 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
9992 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
9993 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
9996 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
9997 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
9998 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
9999 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
10000 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
10001 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
10002 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
10003 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
10004 IDirectDrawSurface7_Unlock(surface7
, NULL
);
10008 IDirectDrawSurface7_Release(surface7
);
10009 IDirectDrawSurface_Release(surface
);
10012 refcount
= IDirectDraw7_Release(ddraw
);
10013 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
10016 static void test_texture_load(void)
10018 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10019 static D3DTLVERTEX tquad
[] =
10021 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
10022 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
10023 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
10024 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
10026 D3DTEXTUREHANDLE dst_texture_handle
, src_texture_handle
;
10027 IDirectDrawSurface
*dst_surface
, *src_surface
;
10028 IDirect3DExecuteBuffer
*execute_buffer
;
10029 D3DEXECUTEBUFFERDESC exec_desc
;
10030 IDirect3DMaterial
*background
;
10031 IDirect3DViewport
*viewport
;
10032 DDSURFACEDESC surface_desc
;
10033 IDirect3DTexture
*texture
;
10034 IDirect3DDevice
*device
;
10035 IDirectDrawSurface
*rt
;
10036 IDirectDraw
*ddraw
;
10045 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
10046 0, 0, 640, 480, 0, 0, 0, 0);
10047 ddraw
= create_ddraw();
10048 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10049 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10051 skip("Failed to create a 3D device, skipping test.\n");
10052 IDirectDraw_Release(ddraw
);
10053 DestroyWindow(window
);
10057 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
10058 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10060 background
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
10061 viewport
= create_viewport(device
, 0, 0, 640, 480);
10062 viewport_set_background(device
, viewport
, background
);
10064 memset(&exec_desc
, 0, sizeof(exec_desc
));
10065 exec_desc
.dwSize
= sizeof(exec_desc
);
10066 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
10067 exec_desc
.dwBufferSize
= 1024;
10068 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
10069 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
10070 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
10072 memset(&surface_desc
, 0, sizeof(surface_desc
));
10073 surface_desc
.dwSize
= sizeof(surface_desc
);
10074 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10075 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10076 surface_desc
.dwWidth
= 256;
10077 surface_desc
.dwHeight
= 256;
10078 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10079 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10080 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
10081 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10082 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10083 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10085 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
10086 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10087 hr
= IDirectDrawSurface_QueryInterface(src_surface
, &IID_IDirect3DTexture
, (void **)&texture
);
10088 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
10089 hr
= IDirect3DTexture_GetHandle(texture
, device
, &src_texture_handle
);
10090 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
10091 IDirect3DTexture_Release(texture
);
10093 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
10094 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10095 hr
= IDirectDrawSurface_QueryInterface(dst_surface
, &IID_IDirect3DTexture
, (void **)&texture
);
10096 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
10097 hr
= IDirect3DTexture_GetHandle(texture
, device
, &dst_texture_handle
);
10098 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
10099 IDirect3DTexture_Release(texture
);
10101 memset(&fx
, 0, sizeof(fx
));
10102 fx
.dwSize
= sizeof(fx
);
10103 U5(fx
).dwFillColor
= 0x0000ffff;
10104 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10105 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
10107 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
10108 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
10109 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
10110 ptr
= (BYTE
*)exec_desc
.lpData
+ sizeof(tquad
);
10111 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
10112 emit_texture_load(&ptr
, dst_texture_handle
, src_texture_handle
);
10113 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, dst_texture_handle
);
10114 emit_tquad(&ptr
, 0);
10116 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- sizeof(tquad
);
10117 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
10118 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
10120 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10121 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
10122 color
= get_surface_color(rt
, 320, 240);
10123 ok(compare_color(color
, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", color
);
10124 set_execute_data(execute_buffer
, 4, sizeof(tquad
), inst_length
);
10125 hr
= IDirect3DDevice_BeginScene(device
);
10126 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10127 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
10128 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
10129 hr
= IDirect3DDevice_EndScene(device
);
10130 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10131 color
= get_surface_color(rt
, 320, 240);
10132 ok(compare_color(color
, 0x0000ffff, 1), "Got unexpected color 0x%08x.\n", color
);
10134 memset(&fx
, 0, sizeof(fx
));
10135 fx
.dwSize
= sizeof(fx
);
10136 U5(fx
).dwFillColor
= 0x000000ff;
10137 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10138 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
10140 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10141 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
10142 color
= get_surface_color(rt
, 320, 240);
10143 ok(compare_color(color
, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", color
);
10144 set_execute_data(execute_buffer
, 4, sizeof(tquad
), inst_length
);
10145 hr
= IDirect3DDevice_BeginScene(device
);
10146 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10147 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
10148 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
10149 hr
= IDirect3DDevice_EndScene(device
);
10150 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10151 color
= get_surface_color(rt
, 320, 240);
10152 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
10154 IDirectDrawSurface_Release(dst_surface
);
10155 IDirectDrawSurface_Release(src_surface
);
10156 IDirectDrawSurface_Release(rt
);
10157 IDirect3DExecuteBuffer_Release(execute_buffer
);
10158 IDirect3DMaterial_Release(background
);
10159 destroy_viewport(device
, viewport
);
10160 IDirect3DDevice_Release(device
);
10161 refcount
= IDirectDraw_Release(ddraw
);
10162 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
10163 DestroyWindow(window
);
10168 IDirectDraw
*ddraw
;
10169 DEVMODEW current_mode
;
10172 if (!(ddraw
= create_ddraw()))
10174 skip("Failed to create a ddraw object, skipping tests.\n");
10177 IDirectDraw_Release(ddraw
);
10179 memset(¤t_mode
, 0, sizeof(current_mode
));
10180 current_mode
.dmSize
= sizeof(current_mode
);
10181 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
10182 registry_mode
.dmSize
= sizeof(registry_mode
);
10183 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
10184 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
10185 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
10187 skip("Current mode does not match registry mode, skipping test.\n");
10191 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
10192 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
10194 test_coop_level_create_device_window();
10195 test_clipper_blt();
10196 test_coop_level_d3d_state();
10197 test_surface_interface_mismatch();
10198 test_coop_level_threaded();
10207 test_window_style();
10208 test_redundant_mode_set();
10209 test_coop_level_mode_set();
10210 test_coop_level_mode_set_multi();
10212 test_coop_level_surf_create();
10213 test_coop_level_multi_window();
10214 test_clear_rect_count();
10215 test_coop_level_activateapp();
10216 test_unsupported_formats();
10218 test_primary_caps();
10219 test_surface_lock();
10220 test_surface_discard();
10222 test_sysmem_overlay();
10223 test_primary_palette();
10224 test_surface_attachment();
10225 test_pixel_format();
10226 test_create_surface_pitch();
10228 test_palette_complex();
10232 test_palette_gdi();
10233 test_palette_alpha();
10234 test_lost_device();
10235 test_surface_desc_lock();
10236 test_texturemapblend();
10237 test_viewport_clear_rect();
10239 test_colorkey_precision();
10240 test_range_colorkey();
10242 test_lockrect_invalid();
10243 test_yv12_overlay();
10244 test_offscreen_overlay();
10245 test_overlay_rect();
10248 test_transform_vertices();
10249 test_display_mode_surface_pixel_format();
10250 test_surface_desc_size();
10251 test_texture_load();