2 * Copyright 2011 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "wine/test.h"
34 struct create_window_thread_param
37 HANDLE window_created
;
38 HANDLE destroy_window
;
42 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
52 if (abs(x
- y
) > ulps
)
58 static BOOL
compare_vec4(struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
60 return compare_float(vec
->x
, x
, ulps
)
61 && compare_float(vec
->y
, y
, ulps
)
62 && compare_float(vec
->z
, z
, ulps
)
63 && compare_float(vec
->w
, w
, ulps
);
66 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
68 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
70 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
72 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
74 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
78 static DWORD WINAPI
create_window_thread_proc(void *param
)
80 struct create_window_thread_param
*p
= param
;
84 p
->window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
85 0, 0, 640, 480, 0, 0, 0, 0);
86 ret
= SetEvent(p
->window_created
);
87 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
93 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
))
94 DispatchMessage(&msg
);
95 res
= WaitForSingleObject(p
->destroy_window
, 100);
96 if (res
== WAIT_OBJECT_0
)
98 if (res
!= WAIT_TIMEOUT
)
100 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
105 DestroyWindow(p
->window
);
110 static void create_window_thread(struct create_window_thread_param
*p
)
114 p
->window_created
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
115 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
116 p
->destroy_window
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
117 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
118 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
119 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
120 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
121 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
124 static void destroy_window_thread(struct create_window_thread_param
*p
)
126 SetEvent(p
->destroy_window
);
127 WaitForSingleObject(p
->thread
, INFINITE
);
128 CloseHandle(p
->destroy_window
);
129 CloseHandle(p
->window_created
);
130 CloseHandle(p
->thread
);
133 static D3DCOLOR
get_surface_color(IDirectDrawSurface4
*surface
, UINT x
, UINT y
)
135 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
136 DDSURFACEDESC2 surface_desc
;
140 memset(&surface_desc
, 0, sizeof(surface_desc
));
141 surface_desc
.dwSize
= sizeof(surface_desc
);
143 hr
= IDirectDrawSurface4_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
144 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
148 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
150 hr
= IDirectDrawSurface4_Unlock(surface
, &rect
);
151 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
156 static HRESULT CALLBACK
enum_z_fmt(DDPIXELFORMAT
*format
, void *ctx
)
158 DDPIXELFORMAT
*z_fmt
= ctx
;
160 if (U1(*format
).dwZBufferBitDepth
> U1(*z_fmt
).dwZBufferBitDepth
)
166 static IDirectDraw4
*create_ddraw(void)
168 IDirectDraw4
*ddraw4
;
172 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
175 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw4
, (void **)&ddraw4
);
176 IDirectDraw_Release(ddraw1
);
183 static IDirect3DDevice3
*create_device(HWND window
, DWORD coop_level
)
185 IDirectDrawSurface4
*surface
, *ds
;
186 IDirect3DDevice3
*device
= NULL
;
187 DDSURFACEDESC2 surface_desc
;
188 IDirectDraw4
*ddraw4
;
193 if (!(ddraw4
= create_ddraw()))
196 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, coop_level
);
197 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
199 memset(&surface_desc
, 0, sizeof(surface_desc
));
200 surface_desc
.dwSize
= sizeof(surface_desc
);
201 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
202 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
203 surface_desc
.dwWidth
= 640;
204 surface_desc
.dwHeight
= 480;
206 hr
= IDirectDraw4_CreateSurface(ddraw4
, &surface_desc
, &surface
, NULL
);
207 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
209 if (coop_level
& DDSCL_NORMAL
)
211 IDirectDrawClipper
*clipper
;
213 hr
= IDirectDraw4_CreateClipper(ddraw4
, 0, &clipper
, NULL
);
214 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
215 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
216 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
217 hr
= IDirectDrawSurface4_SetClipper(surface
, clipper
);
218 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
219 IDirectDrawClipper_Release(clipper
);
222 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirect3D3
, (void **)&d3d3
);
223 IDirectDraw4_Release(ddraw4
);
226 IDirectDrawSurface4_Release(surface
);
230 memset(&z_fmt
, 0, sizeof(z_fmt
));
231 hr
= IDirect3D3_EnumZBufferFormats(d3d3
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
232 if (FAILED(hr
) || !z_fmt
.dwSize
)
234 IDirect3D3_Release(d3d3
);
235 IDirectDrawSurface4_Release(surface
);
239 memset(&surface_desc
, 0, sizeof(surface_desc
));
240 surface_desc
.dwSize
= sizeof(surface_desc
);
241 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
242 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
243 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
244 surface_desc
.dwWidth
= 640;
245 surface_desc
.dwHeight
= 480;
246 hr
= IDirectDraw4_CreateSurface(ddraw4
, &surface_desc
, &ds
, NULL
);
247 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
250 IDirect3D3_Release(d3d3
);
251 IDirectDrawSurface4_Release(surface
);
255 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
256 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
257 IDirectDrawSurface4_Release(ds
);
260 IDirect3D3_Release(d3d3
);
261 IDirectDrawSurface4_Release(surface
);
265 hr
= IDirect3D3_CreateDevice(d3d3
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
266 IDirect3D3_Release(d3d3
);
267 IDirectDrawSurface4_Release(surface
);
274 static void test_process_vertices(void)
276 IDirect3DVertexBuffer
*src_vb
, *dst_vb
;
277 IDirect3DViewport3
*viewport
;
278 D3DVERTEXBUFFERDESC vb_desc
;
279 IDirect3DDevice3
*device
;
280 struct vec3
*src_data
;
281 struct vec4
*dst_data
;
288 static D3DMATRIX identity
=
290 1.0f
, 0.0f
, 0.0f
, 0.0f
,
291 0.0f
, 1.0f
, 0.0f
, 0.0f
,
292 0.0f
, 0.0f
, 1.0f
, 0.0f
,
293 0.0f
, 0.0f
, 0.0f
, 1.0f
,
295 static D3DMATRIX projection
=
297 1.0f
, 0.0f
, 0.0f
, 0.0f
,
298 0.0f
, 1.0f
, 0.0f
, 0.0f
,
299 0.0f
, 0.0f
, 1.0f
, 0.0f
,
300 6.0f
, 7.0f
, 8.0f
, 1.0f
,
303 window
= CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW
,
304 0, 0, 640, 480, 0, 0, 0, 0);
305 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
307 skip("Failed to create a 3D device, skipping test.\n");
308 DestroyWindow(window
);
312 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d3
);
313 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
315 memset(&vb_desc
, 0, sizeof(vb_desc
));
316 vb_desc
.dwSize
= sizeof(vb_desc
);
317 vb_desc
.dwFVF
= D3DFVF_XYZ
;
318 vb_desc
.dwNumVertices
= 3;
319 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &src_vb
, 0, NULL
);
320 ok(SUCCEEDED(hr
), "Failed to create source vertex buffer, hr %#x.\n", hr
);
322 hr
= IDirect3DVertexBuffer_Lock(src_vb
, DDLOCK_WRITEONLY
, (void **)&src_data
, NULL
);
323 ok(SUCCEEDED(hr
), "Failed to lock source vertex buffer, hr %#x.\n", hr
);
324 src_data
[0].x
= -1.0f
;
325 src_data
[0].y
= -1.0f
;
326 src_data
[0].z
= -1.0f
;
327 src_data
[1].x
= 0.0f
;
328 src_data
[1].y
= 0.0f
;
329 src_data
[1].z
= 0.0f
;
330 src_data
[2].x
= 1.0f
;
331 src_data
[2].y
= 1.0f
;
332 src_data
[2].z
= 1.0f
;
333 hr
= IDirect3DVertexBuffer_Unlock(src_vb
);
334 ok(SUCCEEDED(hr
), "Failed to unlock source vertex buffer, hr %#x.\n", hr
);
336 memset(&vb_desc
, 0, sizeof(vb_desc
));
337 vb_desc
.dwSize
= sizeof(vb_desc
);
338 vb_desc
.dwFVF
= D3DFVF_XYZRHW
;
339 vb_desc
.dwNumVertices
= 3;
340 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &dst_vb
, 0, NULL
);
341 ok(SUCCEEDED(hr
), "Failed to create destination vertex buffer, hr %#x.\n", hr
);
343 hr
= IDirect3D3_CreateViewport(d3d3
, &viewport
, NULL
);
344 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
345 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
346 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
347 vp2
.dwSize
= sizeof(vp2
);
354 vp2
.dvClipWidth
= 4.0f
;
355 vp2
.dvClipHeight
= 5.0f
;
358 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
359 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
360 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
361 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
363 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &identity
);
364 ok(SUCCEEDED(hr
), "Failed to set world transformation, hr %#x.\n", hr
);
365 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &identity
);
366 ok(SUCCEEDED(hr
), "Failed to set view transformation, hr %#x.\n", hr
);
367 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &identity
);
368 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
370 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
371 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
373 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
374 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
375 ok(compare_vec4(&dst_data
[0], -6.500e+1f
, +1.800e+2f
, +2.000e-1f
, +1.000e+0f
, 4096),
376 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
377 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
378 ok(compare_vec4(&dst_data
[1], -4.000e+1f
, +1.400e+2f
, +4.000e-1f
, +1.000e+0f
, 4096),
379 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
380 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
381 ok(compare_vec4(&dst_data
[2], -1.500e+1f
, +1.000e+2f
, +6.000e-1f
, +1.000e+0f
, 4096),
382 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
383 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
384 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
385 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
387 hr
= IDirect3DDevice3_MultiplyTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &projection
);
388 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
390 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
391 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
393 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
394 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
395 ok(compare_vec4(&dst_data
[0], +8.500e+1f
, -1.000e+2f
, +1.800e+0f
, +1.000e+0f
, 4096),
396 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
397 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
398 ok(compare_vec4(&dst_data
[1], +1.100e+2f
, -1.400e+2f
, +2.000e+0f
, +1.000e+0f
, 4096),
399 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
400 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
401 ok(compare_vec4(&dst_data
[2], +1.350e+2f
, -1.800e+2f
, +2.200e+0f
, +1.000e+0f
, 4096),
402 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
403 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
404 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
405 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
407 vp2
.dwSize
= sizeof(vp2
);
414 vp2
.dvClipWidth
= 2.0f
;
415 vp2
.dvClipHeight
= 4.0f
;
418 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
419 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
421 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
422 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
424 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
425 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
426 ok(compare_vec4(&dst_data
[0], +7.500e+1f
, +4.000e+1f
, -8.000e-1f
, +1.000e+0f
, 4096),
427 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
428 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
429 ok(compare_vec4(&dst_data
[1], +1.200e+2f
, +2.000e+1f
, -1.000e+0f
, +1.000e+0f
, 4096),
430 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
431 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
432 ok(compare_vec4(&dst_data
[2], +1.650e+2f
, +0.000e+0f
, -1.200e+0f
, +1.000e+0f
, 4096),
433 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
434 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
435 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
436 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
438 vp1
.dwSize
= sizeof(vp1
);
449 hr
= IDirect3DViewport3_SetViewport(viewport
, &vp1
);
450 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
452 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
453 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
455 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
456 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
457 ok(compare_vec4(&dst_data
[0], +1.100e+2f
, +6.800e+1f
, +7.000e+0f
, +1.000e+0f
, 4096),
458 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
459 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
460 ok(compare_vec4(&dst_data
[1], +1.170e+2f
, +6.600e+1f
, +8.000e+0f
, +1.000e+0f
, 4096),
461 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
462 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
463 ok(compare_vec4(&dst_data
[2], +1.240e+2f
, +6.400e+1f
, +9.000e+0f
, +1.000e+0f
, 4096),
464 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
465 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
466 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
467 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
469 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
470 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
472 IDirect3DVertexBuffer_Release(dst_vb
);
473 IDirect3DVertexBuffer_Release(src_vb
);
474 IDirect3DViewport3_Release(viewport
);
475 IDirect3D3_Release(d3d3
);
476 IDirect3DDevice3_Release(device
);
477 DestroyWindow(window
);
480 static void test_coop_level_create_device_window(void)
482 HWND focus_window
, device_window
;
486 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
487 0, 0, 640, 480, 0, 0, 0, 0);
488 if (!(ddraw
= create_ddraw()))
490 skip("Failed to create a ddraw object, skipping test.\n");
491 DestroyWindow(focus_window
);
495 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
496 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
497 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
498 ok(!device_window
, "Unexpected device window found.\n");
499 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
500 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
501 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
502 ok(!device_window
, "Unexpected device window found.\n");
503 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
504 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
505 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
506 ok(!device_window
, "Unexpected device window found.\n");
507 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
508 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
509 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
510 ok(!device_window
, "Unexpected device window found.\n");
511 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
512 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
513 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
514 ok(!device_window
, "Unexpected device window found.\n");
516 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
517 if (broken(hr
== DDERR_INVALIDPARAMS
))
519 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
520 IDirectDraw4_Release(ddraw
);
521 DestroyWindow(focus_window
);
525 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
526 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
527 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
528 ok(!device_window
, "Unexpected device window found.\n");
529 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
530 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
531 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
532 ok(!device_window
, "Unexpected device window found.\n");
534 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
535 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
536 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
537 ok(!device_window
, "Unexpected device window found.\n");
538 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
539 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
540 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
541 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
542 ok(!!device_window
, "Device window not found.\n");
544 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
545 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
546 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
547 ok(!device_window
, "Unexpected device window found.\n");
548 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
549 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
550 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
551 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
552 ok(!!device_window
, "Device window not found.\n");
554 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
555 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
556 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
557 ok(!device_window
, "Unexpected device window found.\n");
558 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
559 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
560 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
561 ok(!device_window
, "Unexpected device window found.\n");
562 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
563 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
564 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
565 ok(!device_window
, "Unexpected device window found.\n");
566 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
567 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
568 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
569 ok(!!device_window
, "Device window not found.\n");
571 IDirectDraw4_Release(ddraw
);
572 DestroyWindow(focus_window
);
575 static void test_clipper_blt(void)
577 IDirectDrawSurface4
*src_surface
, *dst_surface
;
578 RECT client_rect
, src_rect
, *rect
;
579 IDirectDrawClipper
*clipper
;
580 DDSURFACEDESC2 surface_desc
;
581 unsigned int i
, j
, x
, y
;
592 static const DWORD src_data
[] =
594 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
595 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
596 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
598 static const D3DCOLOR expected1
[] =
600 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
601 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
602 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
603 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
605 static const D3DCOLOR expected2
[] =
607 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
608 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
609 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
610 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
613 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
614 10, 10, 640, 480, 0, 0, 0, 0);
615 ShowWindow(window
, SW_SHOW
);
616 if (!(ddraw
= create_ddraw()))
618 skip("Failed to create a ddraw object, skipping test.\n");
619 DestroyWindow(window
);
623 ret
= GetClientRect(window
, &client_rect
);
624 ok(ret
, "Failed to get client rect.\n");
625 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
626 ok(ret
, "Failed to map client rect.\n");
628 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
629 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
631 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
632 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
633 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
634 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
635 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
636 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
637 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
638 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
639 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
640 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
641 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
642 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
643 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
644 ok(rgn_data
->rdh
.nCount
== 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
645 ok(rgn_data
->rdh
.nRgnSize
== 16, "Got unexpected region size %u.\n", rgn_data
->rdh
.nRgnSize
);
646 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
647 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
648 rgn_data
->rdh
.rcBound
.left
, rgn_data
->rdh
.rcBound
.top
,
649 rgn_data
->rdh
.rcBound
.right
, rgn_data
->rdh
.rcBound
.bottom
,
650 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
651 rect
= (RECT
*)&rgn_data
->Buffer
[0];
652 ok(EqualRect(rect
, &client_rect
),
653 "Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
654 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
655 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
656 HeapFree(GetProcessHeap(), 0, rgn_data
);
658 r1
= CreateRectRgn(0, 0, 320, 240);
659 ok(!!r1
, "Failed to create region.\n");
660 r2
= CreateRectRgn(320, 240, 640, 480);
661 ok(!!r2
, "Failed to create region.\n");
662 CombineRgn(r1
, r1
, r2
, RGN_OR
);
663 ret
= GetRegionData(r1
, 0, NULL
);
664 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
665 ret
= GetRegionData(r1
, ret
, rgn_data
);
666 ok(!!ret
, "Failed to get region data.\n");
671 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
672 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
673 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
674 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
675 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
676 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
678 HeapFree(GetProcessHeap(), 0, rgn_data
);
680 memset(&surface_desc
, 0, sizeof(surface_desc
));
681 surface_desc
.dwSize
= sizeof(surface_desc
);
682 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
683 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
684 surface_desc
.dwWidth
= 640;
685 surface_desc
.dwHeight
= 480;
686 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
687 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
688 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
689 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
690 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
691 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
693 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
694 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
695 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
696 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
698 memset(&fx
, 0, sizeof(fx
));
699 fx
.dwSize
= sizeof(fx
);
700 hr
= IDirectDrawSurface4_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
701 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
702 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
703 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
705 hr
= IDirectDrawSurface4_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
706 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
707 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
708 ptr
= surface_desc
.lpSurface
;
709 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
710 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
711 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
712 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
713 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
715 hr
= IDirectDrawSurface4_SetClipper(dst_surface
, clipper
);
716 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
718 SetRect(&src_rect
, 1, 1, 5, 2);
719 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
720 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
721 for (i
= 0; i
< 4; ++i
)
723 for (j
= 0; j
< 4; ++j
)
725 x
= 80 * ((2 * j
) + 1);
726 y
= 60 * ((2 * i
) + 1);
727 color
= get_surface_color(dst_surface
, x
, y
);
728 ok(compare_color(color
, expected1
[i
* 4 + j
], 1),
729 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
733 U5(fx
).dwFillColor
= 0xff0000ff;
734 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
735 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
736 for (i
= 0; i
< 4; ++i
)
738 for (j
= 0; j
< 4; ++j
)
740 x
= 80 * ((2 * j
) + 1);
741 y
= 60 * ((2 * i
) + 1);
742 color
= get_surface_color(dst_surface
, x
, y
);
743 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
744 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
748 hr
= IDirectDrawSurface4_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
749 ok(hr
== DDERR_BLTFASTCANTCLIP
, "Got unexpected hr %#x.\n", hr
);
751 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
752 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
753 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
754 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
755 DestroyWindow(window
);
756 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
757 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
758 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
759 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
760 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
761 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
762 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
763 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
764 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
765 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
766 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
767 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
769 IDirectDrawSurface4_Release(dst_surface
);
770 IDirectDrawSurface4_Release(src_surface
);
771 IDirectDrawClipper_Release(clipper
);
772 IDirectDraw4_Release(ddraw
);
775 static void test_coop_level_d3d_state(void)
777 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
778 IDirectDrawSurface4
*rt
, *surface
;
779 IDirect3DViewport3
*viewport
;
780 IDirect3DDevice3
*device
;
789 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
790 0, 0, 640, 480, 0, 0, 0, 0);
791 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
793 skip("Failed to create D3D device, skipping test.\n");
794 DestroyWindow(window
);
798 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
799 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
801 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
802 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
803 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
804 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
805 memset(&vp
, 0, sizeof(vp
));
806 vp
.dwSize
= sizeof(vp
);
813 vp
.dvClipWidth
= 2.0f
;
814 vp
.dvClipHeight
= 2.0f
;
817 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
818 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
820 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
821 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
822 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
823 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
824 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
825 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
826 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
827 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
828 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
829 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
830 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
831 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
832 color
= get_surface_color(rt
, 320, 240);
833 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
835 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
836 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
837 IDirect3D3_Release(d3d
);
838 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
839 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
840 hr
= IDirectDrawSurface4_IsLost(rt
);
841 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
842 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
843 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
844 IDirectDraw4_Release(ddraw
);
846 hr
= IDirect3DDevice3_GetRenderTarget(device
, &surface
);
847 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
848 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
849 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
850 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
851 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
852 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
853 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
854 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
855 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
856 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
857 color
= get_surface_color(rt
, 320, 240);
858 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
860 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
861 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
862 IDirect3DViewport3_Release(viewport
);
863 IDirectDrawSurface4_Release(surface
);
864 IDirectDrawSurface4_Release(rt
);
865 IDirect3DDevice3_Release(device
);
866 DestroyWindow(window
);
869 static void test_surface_interface_mismatch(void)
871 IDirectDraw4
*ddraw
= NULL
;
872 IDirect3D3
*d3d
= NULL
;
873 IDirectDrawSurface4
*surface
= NULL
, *ds
;
874 IDirectDrawSurface3
*surface3
= NULL
;
875 IDirect3DDevice3
*device
= NULL
;
876 IDirect3DViewport3
*viewport
= NULL
;
877 DDSURFACEDESC2 surface_desc
;
884 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
886 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
887 0, 0, 640, 480, 0, 0, 0, 0);
889 if (!(ddraw
= create_ddraw()))
891 skip("Failed to create a ddraw object, skipping test.\n");
895 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
896 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
898 memset(&surface_desc
, 0, sizeof(surface_desc
));
899 surface_desc
.dwSize
= sizeof(surface_desc
);
900 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
901 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
902 surface_desc
.dwWidth
= 640;
903 surface_desc
.dwHeight
= 480;
905 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
906 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
908 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
909 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface3, hr %#x.\n", hr
);
911 hr
= IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
);
914 skip("Failed to get the IDirect3D7 interface, skipping test.\n");
918 memset(&z_fmt
, 0, sizeof(z_fmt
));
919 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
920 if (FAILED(hr
) || !z_fmt
.dwSize
)
922 skip("No depth buffer formats available, skipping test.\n");
926 memset(&surface_desc
, 0, sizeof(surface_desc
));
927 surface_desc
.dwSize
= sizeof(surface_desc
);
928 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
929 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
930 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
931 surface_desc
.dwWidth
= 640;
932 surface_desc
.dwHeight
= 480;
933 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
934 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
938 /* Using a different surface interface version still works */
939 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
940 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
941 refcount
= IDirectDrawSurface4_Release(ds
);
942 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
947 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface4
*)surface3
, &device
, NULL
);
948 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
952 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
953 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
954 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
955 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
956 memset(&vp
, 0, sizeof(vp
));
957 vp
.dwSize
= sizeof(vp
);
964 vp
.dvClipWidth
= 2.0f
;
965 vp
.dvClipHeight
= 2.0f
;
968 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
969 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
971 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
972 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
973 color
= get_surface_color(surface
, 320, 240);
974 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
979 IDirect3DDevice3_DeleteViewport(device
, viewport
);
980 IDirect3DViewport3_Release(viewport
);
982 if (surface3
) IDirectDrawSurface3_Release(surface3
);
983 if (surface
) IDirectDrawSurface4_Release(surface
);
984 if (device
) IDirect3DDevice3_Release(device
);
985 if (d3d
) IDirect3D3_Release(d3d
);
986 if (ddraw
) IDirectDraw4_Release(ddraw
);
987 DestroyWindow(window
);
990 static void test_coop_level_threaded(void)
992 struct create_window_thread_param p
;
996 if (!(ddraw
= create_ddraw()))
998 skip("Failed to create a ddraw object, skipping test.\n");
1001 create_window_thread(&p
);
1003 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1004 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1006 IDirectDraw4_Release(ddraw
);
1007 destroy_window_thread(&p
);
1010 static IDirectDrawSurface4
*get_depth_stencil(IDirect3DDevice3
*device
)
1012 IDirectDrawSurface4
*rt
, *ret
;
1013 DDSCAPS2 caps
= {DDSCAPS_ZBUFFER
, 0, 0, 0};
1016 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1017 ok(SUCCEEDED(hr
), "Failed to get the render target, hr %#x.\n", hr
);
1018 hr
= IDirectDrawSurface4_GetAttachedSurface(rt
, &caps
, &ret
);
1019 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
1020 IDirectDrawSurface4_Release(rt
);
1024 static void test_depth_blit(void)
1033 { -1.0, 1.0, 0.50f
, 0xff00ff00},
1034 { 1.0, 1.0, 0.50f
, 0xff00ff00},
1035 { -1.0, -1.0, 0.50f
, 0xff00ff00},
1036 { 1.0, -1.0, 0.50f
, 0xff00ff00},
1038 static const D3DCOLOR expected_colors
[4][4] =
1040 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1041 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1042 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1043 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1045 DDSURFACEDESC2 ddsd_new
, ddsd_existing
;
1047 IDirect3DDevice3
*device
;
1048 IDirectDrawSurface4
*ds1
, *ds2
, *ds3
, *rt
;
1049 IDirect3DViewport3
*viewport
;
1050 D3DVIEWPORT2 vp_data
;
1051 RECT src_rect
, dst_rect
;
1056 IDirectDraw4
*ddraw
;
1061 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1062 0, 0, 640, 480, 0, 0, 0, 0);
1063 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1065 skip("Failed to create D3D device, skipping test.\n");
1066 DestroyWindow(window
);
1070 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1071 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
1072 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1073 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
1074 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
1075 ok(SUCCEEDED(hr
), "Failed to create a viewport, hr %#x.\n", hr
);
1076 IDirect3D3_Release(d3d
);
1078 ds1
= get_depth_stencil(device
);
1080 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1081 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1082 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1083 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1084 hr
= IDirectDrawSurface4_GetSurfaceDesc(ds1
, &ddsd_existing
);
1085 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1086 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1087 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1088 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1089 U4(ddsd_new
).ddpfPixelFormat
= U4(ddsd_existing
).ddpfPixelFormat
;
1090 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1091 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1092 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1093 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1094 IDirectDraw4_Release(ddraw
);
1096 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
1097 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1098 memset(&vp_data
, 0, sizeof(vp_data
));
1099 vp_data
.dwSize
= sizeof(vp_data
);
1100 vp_data
.dwWidth
= ddsd_existing
.dwWidth
;
1101 vp_data
.dwHeight
= ddsd_existing
.dwHeight
;
1102 vp_data
.dvMaxZ
= 1.0;
1103 vp_data
.dvClipX
= -1.0f
;
1104 vp_data
.dvClipWidth
= 2.0f
;
1105 vp_data
.dvClipY
= 1.0f
;
1106 vp_data
.dvClipHeight
= 2.0f
;
1107 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp_data
);
1108 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
1109 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1110 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
1112 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1113 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
1114 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1115 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
1116 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
1117 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
1119 U1(d3drect
).x1
= U2(d3drect
).y1
= 0;
1120 U3(d3drect
).x2
= vp_data
.dwWidth
; U4(d3drect
).y2
= vp_data
.dwHeight
;
1121 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
1122 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
1125 SetRect(&src_rect
, 0, 0, 320, 240);
1126 SetRect(&dst_rect
, 0, 0, 320, 240);
1127 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1128 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1129 /* Different locations. */
1130 SetRect(&src_rect
, 0, 0, 320, 240);
1131 SetRect(&dst_rect
, 320, 240, 640, 480);
1132 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1133 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1135 SetRect(&src_rect
, 0, 0, 320, 240);
1136 SetRect(&dst_rect
, 0, 0, 640, 480);
1137 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1138 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1140 SetRect(&src_rect
, 0, 480, 640, 0);
1141 SetRect(&dst_rect
, 0, 0, 640, 480);
1142 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1143 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1144 SetRect(&src_rect
, 0, 0, 640, 480);
1145 SetRect(&dst_rect
, 0, 480, 640, 0);
1146 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1147 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1148 /* Full, explicit. */
1149 SetRect(&src_rect
, 0, 0, 640, 480);
1150 SetRect(&dst_rect
, 0, 0, 640, 480);
1151 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1152 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1153 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1155 /* Depth blit inside a BeginScene / EndScene pair */
1156 hr
= IDirect3DDevice3_BeginScene(device
);
1157 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1158 /* From the current depth stencil */
1159 hr
= IDirectDrawSurface4_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1160 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1161 /* To the current depth stencil */
1162 hr
= IDirectDrawSurface4_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1163 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1164 /* Between unbound surfaces */
1165 hr
= IDirectDrawSurface4_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1166 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1167 hr
= IDirect3DDevice3_EndScene(device
);
1168 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1170 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1171 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1172 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1173 * a reliable result(z = 0.0) */
1174 memset(&fx
, 0, sizeof(fx
));
1175 fx
.dwSize
= sizeof(fx
);
1176 hr
= IDirectDrawSurface4_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1177 ok(SUCCEEDED(hr
), "Failed to clear the source z buffer, hr %#x.\n", hr
);
1179 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
1180 ok(SUCCEEDED(hr
), "Failed to clear the color and z buffers, hr %#x.\n", hr
);
1181 SetRect(&dst_rect
, 0, 0, 320, 240);
1182 hr
= IDirectDrawSurface4_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1183 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1184 IDirectDrawSurface4_Release(ds3
);
1185 IDirectDrawSurface4_Release(ds2
);
1186 IDirectDrawSurface4_Release(ds1
);
1188 hr
= IDirect3DDevice3_BeginScene(device
);
1189 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1190 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
1192 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1193 hr
= IDirect3DDevice3_EndScene(device
);
1194 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1196 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1197 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1198 for (i
= 0; i
< 4; ++i
)
1200 for (j
= 0; j
< 4; ++j
)
1202 unsigned int x
= 80 * ((2 * j
) + 1);
1203 unsigned int y
= 60 * ((2 * i
) + 1);
1204 color
= get_surface_color(rt
, x
, y
);
1205 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1206 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1209 IDirectDrawSurface4_Release(rt
);
1211 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
1212 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#x.\n", hr
);
1213 IDirect3DViewport3_Release(viewport
);
1214 IDirect3DDevice3_Release(device
);
1215 DestroyWindow(window
);
1218 static void test_texture_load_ckey(void)
1220 IDirectDraw4
*ddraw
;
1221 IDirectDrawSurface4
*src
;
1222 IDirectDrawSurface4
*dst
;
1223 IDirect3DTexture2
*src_tex
;
1224 IDirect3DTexture2
*dst_tex
;
1225 DDSURFACEDESC2 ddsd
;
1229 if (!(ddraw
= create_ddraw()))
1231 skip("Failed to create ddraw object, skipping test.\n");
1234 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1235 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1237 memset(&ddsd
, 0, sizeof(ddsd
));
1238 ddsd
.dwSize
= sizeof(ddsd
);
1239 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1240 ddsd
.dwHeight
= 128;
1242 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1243 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1244 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1245 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1246 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1247 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1249 hr
= IDirectDrawSurface4_QueryInterface(src
, &IID_IDirect3DTexture2
, (void **)&src_tex
);
1250 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get Direct3DTexture2 interface, hr %#x.\n", hr
);
1253 /* 64 bit ddraw does not support d3d */
1254 skip("Could not get Direct3DTexture2 interface, skipping texture::Load color keying tests.\n");
1255 IDirectDrawSurface4_Release(dst
);
1256 IDirectDrawSurface4_Release(src
);
1257 IDirectDraw4_Release(ddraw
);
1260 hr
= IDirectDrawSurface4_QueryInterface(dst
, &IID_IDirect3DTexture2
, (void **)&dst_tex
);
1261 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture2 interface, hr %#x.\n", hr
);
1263 /* No surface has a color key */
1264 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1265 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1266 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1267 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1268 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1269 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1270 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1272 /* Source surface has a color key */
1273 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1274 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1275 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1276 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1277 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1278 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1279 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1280 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1281 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1283 /* Both surfaces have a color key: Dest ckey is overwritten */
1284 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1285 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1286 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1287 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1288 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1289 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1290 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1291 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1292 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1294 /* Only the destination has a color key: It is not deleted */
1295 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1296 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1297 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1298 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1299 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1300 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1301 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1302 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1303 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1304 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1306 IDirect3DTexture2_Release(dst_tex
);
1307 IDirect3DTexture2_Release(src_tex
);
1308 IDirectDrawSurface4_Release(dst
);
1309 IDirectDrawSurface4_Release(src
);
1310 IDirectDraw4_Release(ddraw
);
1313 static LONG
get_refcount(IUnknown
*test_iface
)
1315 IUnknown_AddRef(test_iface
);
1316 return IUnknown_Release(test_iface
);
1319 static void test_viewport_interfaces(void)
1321 IDirectDraw4
*ddraw
;
1323 HRESULT hr
, old_d3d_ref
;
1325 IDirect3DViewport
*viewport
;
1326 IDirect3DViewport2
*viewport2
;
1327 IDirect3DViewport3
*viewport3
;
1328 IDirectDrawGammaControl
*gamma
;
1331 if (!(ddraw
= create_ddraw()))
1333 skip("Failed to create ddraw object, skipping test.\n");
1336 hr
= IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
);
1337 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get d3d interface, hr %#x.\n", hr
);
1340 skip("Direct3D not available, skipping tests\n");
1341 IDirectDraw4_Release(ddraw
);
1344 old_d3d_ref
= get_refcount((IUnknown
*)d3d
);
1346 hr
= IDirect3D3_CreateViewport(d3d
, &viewport3
, NULL
);
1347 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1348 ref
= get_refcount((IUnknown
*)viewport3
);
1349 ok(ref
== 1, "Initial IDirect3DViewport3 refcount is %d\n", ref
);
1350 ref
= get_refcount((IUnknown
*)d3d
);
1351 ok(ref
== old_d3d_ref
, "IDirect3D3 refcount is %d\n", ref
);
1353 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1354 hr
= IDirect3DViewport2_QueryInterface(viewport3
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1355 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
1356 ok(gamma
== NULL
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1357 if (SUCCEEDED(hr
)) IDirectDrawGammaControl_Release(gamma
);
1358 /* NULL iid: Segfaults */
1360 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IDirect3DViewport
, (void **)&viewport
);
1361 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport, hr %#x.\n", hr
);
1364 ref
= get_refcount((IUnknown
*)viewport
);
1365 ok(ref
== 2, "IDirect3DViewport refcount is %d\n", ref
);
1366 ref
= get_refcount((IUnknown
*)viewport3
);
1367 ok(ref
== 2, "IDirect3DViewport3 refcount is %d\n", ref
);
1368 IDirect3DViewport_Release(viewport
);
1372 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IDirect3DViewport3
, (void **)&viewport2
);
1373 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport3, hr %#x.\n", hr
);
1376 ref
= get_refcount((IUnknown
*)viewport2
);
1377 ok(ref
== 2, "IDirect3DViewport2 refcount is %d\n", ref
);
1378 ref
= get_refcount((IUnknown
*)viewport3
);
1379 ok(ref
== 2, "IDirect3DViewport3 refcount is %d\n", ref
);
1380 IDirect3DViewport3_Release(viewport2
);
1383 hr
= IDirect3DViewport3_QueryInterface(viewport2
, &IID_IUnknown
, (void **)&unknown
);
1384 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#x.\n", hr
);
1387 ref
= get_refcount((IUnknown
*)viewport3
);
1388 ok(ref
== 2, "IDirect3DViewport3 refcount is %d\n", ref
);
1389 ref
= get_refcount(unknown
);
1390 ok(ref
== 2, "IUnknown refcount is %d\n", ref
);
1391 IUnknown_Release(unknown
);
1394 IDirect3DViewport3_Release(viewport3
);
1395 IDirect3D3_Release(d3d
);
1396 IDirectDraw4_Release(ddraw
);
1401 test_process_vertices();
1402 test_coop_level_create_device_window();
1404 test_coop_level_d3d_state();
1405 test_surface_interface_mismatch();
1406 test_coop_level_threaded();
1408 test_texture_load_ckey();
1409 test_viewport_interfaces();