2 * Copyright 2006 Stefan Dösinger for CodeWeavers
3 * Copyright 2011 Henri Verbeet for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "wine/test.h"
24 static HRESULT (WINAPI
*pDirectDrawCreateEx
)(GUID
*guid
, void **ddraw
, REFIID iid
, IUnknown
*outer_unknown
);
41 struct create_window_thread_param
44 HANDLE window_created
;
45 HANDLE destroy_window
;
49 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
59 if (abs(x
- y
) > ulps
)
65 static BOOL
compare_vec3(struct vec3
*vec
, float x
, float y
, float z
, unsigned int ulps
)
67 return compare_float(vec
->x
, x
, ulps
)
68 && compare_float(vec
->y
, y
, ulps
)
69 && compare_float(vec
->z
, z
, ulps
);
72 static BOOL
compare_vec4(struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
74 return compare_float(vec
->x
, x
, ulps
)
75 && compare_float(vec
->y
, y
, ulps
)
76 && compare_float(vec
->z
, z
, ulps
)
77 && compare_float(vec
->w
, w
, ulps
);
80 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
82 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
84 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
86 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
88 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
92 static DWORD WINAPI
create_window_thread_proc(void *param
)
94 struct create_window_thread_param
*p
= param
;
98 p
->window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
99 0, 0, 640, 480, 0, 0, 0, 0);
100 ret
= SetEvent(p
->window_created
);
101 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
107 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
))
108 DispatchMessage(&msg
);
109 res
= WaitForSingleObject(p
->destroy_window
, 100);
110 if (res
== WAIT_OBJECT_0
)
112 if (res
!= WAIT_TIMEOUT
)
114 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
119 DestroyWindow(p
->window
);
124 static void create_window_thread(struct create_window_thread_param
*p
)
128 p
->window_created
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
129 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
130 p
->destroy_window
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
131 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
132 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
133 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
134 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
135 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
138 static void destroy_window_thread(struct create_window_thread_param
*p
)
140 SetEvent(p
->destroy_window
);
141 WaitForSingleObject(p
->thread
, INFINITE
);
142 CloseHandle(p
->destroy_window
);
143 CloseHandle(p
->window_created
);
144 CloseHandle(p
->thread
);
147 static IDirectDrawSurface7
*get_depth_stencil(IDirect3DDevice7
*device
)
149 IDirectDrawSurface7
*rt
, *ret
;
150 DDSCAPS2 caps
= {DDSCAPS_ZBUFFER
, 0, 0, 0};
153 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
154 ok(SUCCEEDED(hr
), "Failed to get the render target, hr %#x.\n", hr
);
155 hr
= IDirectDrawSurface7_GetAttachedSurface(rt
, &caps
, &ret
);
156 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
157 IDirectDrawSurface7_Release(rt
);
161 static D3DCOLOR
get_surface_color(IDirectDrawSurface7
*surface
, UINT x
, UINT y
)
163 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
164 DDSURFACEDESC2 surface_desc
;
168 memset(&surface_desc
, 0, sizeof(surface_desc
));
169 surface_desc
.dwSize
= sizeof(surface_desc
);
171 hr
= IDirectDrawSurface7_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
, NULL
);
172 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
176 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
178 hr
= IDirectDrawSurface7_Unlock(surface
, &rect
);
179 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
184 static HRESULT CALLBACK
enum_z_fmt(DDPIXELFORMAT
*format
, void *ctx
)
186 DDPIXELFORMAT
*z_fmt
= ctx
;
188 if (U1(*format
).dwZBufferBitDepth
> U1(*z_fmt
).dwZBufferBitDepth
)
194 static IDirectDraw7
*create_ddraw(void)
198 if (FAILED(pDirectDrawCreateEx(NULL
, (void **)&ddraw
, &IID_IDirectDraw7
, NULL
)))
204 static IDirect3DDevice7
*create_device(HWND window
, DWORD coop_level
)
206 IDirectDrawSurface7
*surface
, *ds
;
207 IDirect3DDevice7
*device
= NULL
;
208 DDSURFACEDESC2 surface_desc
;
214 if (!(ddraw
= create_ddraw()))
217 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, coop_level
);
218 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
220 memset(&surface_desc
, 0, sizeof(surface_desc
));
221 surface_desc
.dwSize
= sizeof(surface_desc
);
222 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
223 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
224 surface_desc
.dwWidth
= 640;
225 surface_desc
.dwHeight
= 480;
227 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
228 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
230 if (coop_level
& DDSCL_NORMAL
)
232 IDirectDrawClipper
*clipper
;
234 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
235 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
236 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
237 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
238 hr
= IDirectDrawSurface7_SetClipper(surface
, clipper
);
239 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
240 IDirectDrawClipper_Release(clipper
);
243 hr
= IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d7
);
244 IDirectDraw7_Release(ddraw
);
247 IDirectDrawSurface7_Release(surface
);
251 memset(&z_fmt
, 0, sizeof(z_fmt
));
252 hr
= IDirect3D7_EnumZBufferFormats(d3d7
, &IID_IDirect3DTnLHalDevice
, enum_z_fmt
, &z_fmt
);
253 if (FAILED(hr
) || !z_fmt
.dwSize
)
255 IDirect3D7_Release(d3d7
);
256 IDirectDrawSurface7_Release(surface
);
260 memset(&surface_desc
, 0, sizeof(surface_desc
));
261 surface_desc
.dwSize
= sizeof(surface_desc
);
262 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
263 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
264 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
265 surface_desc
.dwWidth
= 640;
266 surface_desc
.dwHeight
= 480;
267 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
268 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
271 IDirect3D7_Release(d3d7
);
272 IDirectDrawSurface7_Release(surface
);
276 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
277 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
278 IDirectDrawSurface7_Release(ds
);
281 IDirect3D7_Release(d3d7
);
282 IDirectDrawSurface7_Release(surface
);
286 hr
= IDirect3D7_CreateDevice(d3d7
, &IID_IDirect3DTnLHalDevice
, surface
, &device
);
287 IDirect3D7_Release(d3d7
);
288 IDirectDrawSurface7_Release(surface
);
295 static void test_process_vertices(void)
297 IDirect3DVertexBuffer7
*src_vb
, *dst_vb1
, *dst_vb2
;
298 D3DVERTEXBUFFERDESC vb_desc
;
299 IDirect3DDevice7
*device
;
300 struct vec4
*dst_data
;
301 struct vec3
*dst_data2
;
302 struct vec3
*src_data
;
308 static D3DMATRIX world
=
310 0.0f
, 1.0f
, 0.0f
, 0.0f
,
311 1.0f
, 0.0f
, 0.0f
, 0.0f
,
312 0.0f
, 0.0f
, 0.0f
, 1.0f
,
313 0.0f
, 1.0f
, 1.0f
, 1.0f
,
315 static D3DMATRIX view
=
317 2.0f
, 0.0f
, 0.0f
, 0.0f
,
318 0.0f
, -1.0f
, 0.0f
, 0.0f
,
319 0.0f
, 0.0f
, 1.0f
, 0.0f
,
320 0.0f
, 0.0f
, 0.0f
, 3.0f
,
322 static D3DMATRIX proj
=
324 1.0f
, 0.0f
, 0.0f
, 1.0f
,
325 0.0f
, 1.0f
, 1.0f
, 0.0f
,
326 0.0f
, 1.0f
, 1.0f
, 0.0f
,
327 1.0f
, 0.0f
, 0.0f
, 1.0f
,
330 window
= CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW
,
331 0, 0, 640, 480, 0, 0, 0, 0);
332 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
334 skip("Failed to create a ddraw object, skipping test.\n");
335 DestroyWindow(window
);
339 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d7
);
340 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
342 memset(&vb_desc
, 0, sizeof(vb_desc
));
343 vb_desc
.dwSize
= sizeof(vb_desc
);
344 vb_desc
.dwFVF
= D3DFVF_XYZ
;
345 vb_desc
.dwNumVertices
= 4;
346 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &src_vb
, 0);
347 ok(SUCCEEDED(hr
), "Failed to create source vertex buffer, hr %#x.\n", hr
);
349 hr
= IDirect3DVertexBuffer7_Lock(src_vb
, 0, (void **)&src_data
, NULL
);
350 ok(SUCCEEDED(hr
), "Failed to lock source vertex buffer, hr %#x.\n", hr
);
351 src_data
[0].x
= 0.0f
;
352 src_data
[0].y
= 0.0f
;
353 src_data
[0].z
= 0.0f
;
354 src_data
[1].x
= 1.0f
;
355 src_data
[1].y
= 1.0f
;
356 src_data
[1].z
= 1.0f
;
357 src_data
[2].x
= -1.0f
;
358 src_data
[2].y
= -1.0f
;
359 src_data
[2].z
= 0.5f
;
360 src_data
[3].x
= 0.5f
;
361 src_data
[3].y
= -0.5f
;
362 src_data
[3].z
= 0.25f
;
363 hr
= IDirect3DVertexBuffer7_Unlock(src_vb
);
364 ok(SUCCEEDED(hr
), "Failed to unlock source vertex buffer, hr %#x.\n", hr
);
366 memset(&vb_desc
, 0, sizeof(vb_desc
));
367 vb_desc
.dwSize
= sizeof(vb_desc
);
368 vb_desc
.dwFVF
= D3DFVF_XYZRHW
;
369 vb_desc
.dwNumVertices
= 4;
370 /* MSDN says that the last parameter must be 0 - check that. */
371 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &dst_vb1
, 4);
372 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
374 memset(&vb_desc
, 0, sizeof(vb_desc
));
375 vb_desc
.dwSize
= sizeof(vb_desc
);
376 vb_desc
.dwFVF
= D3DFVF_XYZ
;
377 vb_desc
.dwNumVertices
= 5;
378 /* MSDN says that the last parameter must be 0 - check that. */
379 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &dst_vb2
, 12345678);
380 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
382 memset(&vp
, 0, sizeof(vp
));
389 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
390 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
392 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
393 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
394 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb2
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
395 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
397 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
398 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
399 ok(compare_vec4(&dst_data
[0], +1.280e+2f
, +1.280e+2f
, +0.000e+0f
, +1.000e+0f
, 4096),
400 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
401 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
402 ok(compare_vec4(&dst_data
[1], +1.920e+2f
, +6.400e+1f
, +1.000e+0f
, +1.000e+0f
, 4096),
403 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
404 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
405 ok(compare_vec4(&dst_data
[2], +6.400e+1f
, +1.920e+2f
, +5.000e-1f
, +1.000e+0f
, 4096),
406 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
407 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
408 ok(compare_vec4(&dst_data
[3], +1.600e+2f
, +1.600e+2f
, +2.500e-1f
, +1.000e+0f
, 4096),
409 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
410 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
411 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
412 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
414 hr
= IDirect3DVertexBuffer7_Lock(dst_vb2
, 0, (void **)&dst_data2
, NULL
);
415 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
416 /* Small thing without much practical meaning, but I stumbled upon it,
417 * so let's check for it: If the output vertex buffer has no RHW value,
418 * the RHW value of the last vertex is written into the next vertex. */
419 ok(compare_vec3(&dst_data2
[4], +1.000e+0f
, +0.000e+0f
, +0.000e+0f
, 4096),
420 "Got unexpected vertex 4 {%.8e, %.8e, %.8e}.\n",
421 dst_data2
[4].x
, dst_data2
[4].y
, dst_data2
[4].z
);
422 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb2
);
423 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
425 /* Try a more complicated viewport, same vertices. */
426 memset(&vp
, 0, sizeof(vp
));
433 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
434 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
436 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
437 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
439 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
440 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
441 ok(compare_vec4(&dst_data
[0], +1.330e+2f
, +7.000e+1f
, -2.000e+0f
, +1.000e+0f
, 4096),
442 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
443 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
444 ok(compare_vec4(&dst_data
[1], +2.560e+2f
, +5.000e+0f
, +4.000e+0f
, +1.000e+0f
, 4096),
445 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
446 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
447 ok(compare_vec4(&dst_data
[2], +1.000e+1f
, +1.350e+2f
, +1.000e+0f
, +1.000e+0f
, 4096),
448 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
449 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
450 ok(compare_vec4(&dst_data
[3], +1.945e+2f
, +1.025e+2f
, -5.000e-1f
, +1.000e+0f
, 4096),
451 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
452 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
453 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
454 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
456 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &world
);
457 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
458 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &view
);
459 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
460 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &proj
);
461 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
463 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
464 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
466 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
467 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
468 ok(compare_vec4(&dst_data
[0], +2.560e+2f
, +7.000e+1f
, -2.000e+0f
, +3.333e-1f
, 4096),
469 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
470 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
471 ok(compare_vec4(&dst_data
[1], +2.560e+2f
, +7.813e+1f
, -2.750e+0f
, +1.250e-1f
, 4096),
472 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
473 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
474 ok(compare_vec4(&dst_data
[2], +2.560e+2f
, +4.400e+1f
, +4.000e-1f
, +4.000e-1f
, 4096),
475 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
476 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
477 ok(compare_vec4(&dst_data
[3], +2.560e+2f
, +8.182e+1f
, -3.091e+0f
, +3.636e-1f
, 4096),
478 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
479 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
480 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
481 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
483 IDirect3DVertexBuffer7_Release(dst_vb2
);
484 IDirect3DVertexBuffer7_Release(dst_vb1
);
485 IDirect3DVertexBuffer7_Release(src_vb
);
486 IDirect3D7_Release(d3d7
);
487 IDirect3DDevice7_Release(device
);
488 DestroyWindow(window
);
491 static void test_coop_level_create_device_window(void)
493 HWND focus_window
, device_window
;
497 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
498 0, 0, 640, 480, 0, 0, 0, 0);
499 if (!(ddraw
= create_ddraw()))
501 skip("Failed to create a 3D device, skipping test.\n");
502 DestroyWindow(focus_window
);
506 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
507 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
508 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
509 ok(!device_window
, "Unexpected device window found.\n");
510 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
511 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
512 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
513 ok(!device_window
, "Unexpected device window found.\n");
514 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
515 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
516 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
517 ok(!device_window
, "Unexpected device window found.\n");
518 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
519 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
520 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
521 ok(!device_window
, "Unexpected device window found.\n");
522 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
523 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
524 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
525 ok(!device_window
, "Unexpected device window found.\n");
527 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
528 if (broken(hr
== DDERR_INVALIDPARAMS
))
530 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
531 IDirectDraw7_Release(ddraw
);
532 DestroyWindow(focus_window
);
536 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
537 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
538 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
539 ok(!device_window
, "Unexpected device window found.\n");
540 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
541 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
542 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
543 ok(!device_window
, "Unexpected device window found.\n");
545 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
546 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
547 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
548 ok(!device_window
, "Unexpected device window found.\n");
549 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
550 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
551 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
552 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
553 ok(!!device_window
, "Device window not found.\n");
555 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
556 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
557 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
558 ok(!device_window
, "Unexpected device window found.\n");
559 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
560 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
561 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
562 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
563 ok(!!device_window
, "Device window not found.\n");
565 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
566 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
567 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
568 ok(!device_window
, "Unexpected device window found.\n");
569 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
570 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
571 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
572 ok(!device_window
, "Unexpected device window found.\n");
573 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
574 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
575 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
576 ok(!device_window
, "Unexpected device window found.\n");
577 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
578 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
579 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
580 ok(!!device_window
, "Device window not found.\n");
582 IDirectDraw7_Release(ddraw
);
583 DestroyWindow(focus_window
);
586 static void test_clipper_blt(void)
588 IDirectDrawSurface7
*src_surface
, *dst_surface
;
589 RECT client_rect
, src_rect
, *rect
;
590 IDirectDrawClipper
*clipper
;
591 DDSURFACEDESC2 surface_desc
;
592 unsigned int i
, j
, x
, y
;
603 static const DWORD src_data
[] =
605 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
606 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
607 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
609 static const D3DCOLOR expected1
[] =
611 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
612 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
613 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
614 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
616 static const D3DCOLOR expected2
[] =
618 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
619 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
620 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
621 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
624 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
625 10, 10, 640, 480, 0, 0, 0, 0);
626 ShowWindow(window
, SW_SHOW
);
627 if (!(ddraw
= create_ddraw()))
629 skip("Failed to create a ddraw object, skipping test.\n");
630 DestroyWindow(window
);
634 ret
= GetClientRect(window
, &client_rect
);
635 ok(ret
, "Failed to get client rect.\n");
636 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
637 ok(ret
, "Failed to map client rect.\n");
639 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
640 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
642 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
643 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
644 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
645 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
646 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
647 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
648 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
649 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
650 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
651 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
652 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
653 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
654 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
655 ok(rgn_data
->rdh
.nCount
== 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
656 ok(rgn_data
->rdh
.nRgnSize
== 16, "Got unexpected region size %u.\n", rgn_data
->rdh
.nRgnSize
);
657 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
658 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
659 rgn_data
->rdh
.rcBound
.left
, rgn_data
->rdh
.rcBound
.top
,
660 rgn_data
->rdh
.rcBound
.right
, rgn_data
->rdh
.rcBound
.bottom
,
661 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
662 rect
= (RECT
*)&rgn_data
->Buffer
[0];
663 ok(EqualRect(rect
, &client_rect
),
664 "Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
665 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
666 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
667 HeapFree(GetProcessHeap(), 0, rgn_data
);
669 r1
= CreateRectRgn(0, 0, 320, 240);
670 ok(!!r1
, "Failed to create region.\n");
671 r2
= CreateRectRgn(320, 240, 640, 480);
672 ok(!!r2
, "Failed to create region.\n");
673 CombineRgn(r1
, r1
, r2
, RGN_OR
);
674 ret
= GetRegionData(r1
, 0, NULL
);
675 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
676 ret
= GetRegionData(r1
, ret
, rgn_data
);
677 ok(!!ret
, "Failed to get region data.\n");
682 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
683 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
684 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
685 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
686 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
687 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
689 HeapFree(GetProcessHeap(), 0, rgn_data
);
691 memset(&surface_desc
, 0, sizeof(surface_desc
));
692 surface_desc
.dwSize
= sizeof(surface_desc
);
693 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
694 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
695 surface_desc
.dwWidth
= 640;
696 surface_desc
.dwHeight
= 480;
697 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
698 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
699 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
700 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
701 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
702 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
704 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
705 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
706 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
707 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
709 memset(&fx
, 0, sizeof(fx
));
710 fx
.dwSize
= sizeof(fx
);
711 hr
= IDirectDrawSurface7_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
712 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
713 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
714 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
716 hr
= IDirectDrawSurface7_Lock(src_surface
, NULL
, &surface_desc
, 0, NULL
);
717 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
718 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
719 ptr
= surface_desc
.lpSurface
;
720 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
721 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
722 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
723 hr
= IDirectDrawSurface7_Unlock(src_surface
, NULL
);
724 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
726 hr
= IDirectDrawSurface7_SetClipper(dst_surface
, clipper
);
727 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
729 SetRect(&src_rect
, 1, 1, 5, 2);
730 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
731 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
732 for (i
= 0; i
< 4; ++i
)
734 for (j
= 0; j
< 4; ++j
)
736 x
= 80 * ((2 * j
) + 1);
737 y
= 60 * ((2 * i
) + 1);
738 color
= get_surface_color(dst_surface
, x
, y
);
739 ok(compare_color(color
, expected1
[i
* 4 + j
], 1),
740 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
744 U5(fx
).dwFillColor
= 0xff0000ff;
745 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
746 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
747 for (i
= 0; i
< 4; ++i
)
749 for (j
= 0; j
< 4; ++j
)
751 x
= 80 * ((2 * j
) + 1);
752 y
= 60 * ((2 * i
) + 1);
753 color
= get_surface_color(dst_surface
, x
, y
);
754 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
755 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
759 hr
= IDirectDrawSurface7_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
760 ok(hr
== DDERR_BLTFASTCANTCLIP
, "Got unexpected hr %#x.\n", hr
);
762 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
763 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
764 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
765 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
766 DestroyWindow(window
);
767 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
768 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
769 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
770 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
771 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
772 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
773 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
774 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
775 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
776 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
777 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
778 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
780 IDirectDrawSurface7_Release(dst_surface
);
781 IDirectDrawSurface7_Release(src_surface
);
782 IDirectDrawClipper_Release(clipper
);
783 IDirectDraw7_Release(ddraw
);
786 static void test_coop_level_d3d_state(void)
788 IDirectDrawSurface7
*rt
, *surface
;
789 IDirect3DDevice7
*device
;
797 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
798 0, 0, 640, 480, 0, 0, 0, 0);
799 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
801 skip("Failed to create D3D device, skipping test.\n");
802 DestroyWindow(window
);
806 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
807 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
808 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
809 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
810 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
811 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
812 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
813 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
814 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
815 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
816 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
817 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
818 color
= get_surface_color(rt
, 320, 240);
819 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
821 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
822 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
823 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
824 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
825 IDirect3D7_Release(d3d
);
826 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
827 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
828 hr
= IDirectDrawSurface7_IsLost(rt
);
829 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
830 hr
= IDirectDraw7_RestoreAllSurfaces(ddraw
);
831 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
832 IDirectDraw7_Release(ddraw
);
834 hr
= IDirect3DDevice7_GetRenderTarget(device
, &surface
);
835 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
836 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
837 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
838 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
839 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
840 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
841 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
842 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
843 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
844 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
845 color
= get_surface_color(rt
, 320, 240);
846 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
848 IDirectDrawSurface7_Release(surface
);
849 IDirectDrawSurface7_Release(rt
);
850 IDirect3DDevice7_Release(device
);
851 DestroyWindow(window
);
854 static void test_surface_interface_mismatch(void)
856 IDirectDraw7
*ddraw
= NULL
;
857 IDirect3D7
*d3d
= NULL
;
858 IDirectDrawSurface7
*surface
= NULL
, *ds
;
859 IDirectDrawSurface3
*surface3
= NULL
;
860 IDirect3DDevice7
*device
= NULL
;
861 DDSURFACEDESC2 surface_desc
;
868 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
869 0, 0, 640, 480, 0, 0, 0, 0);
871 if (!(ddraw
= create_ddraw()))
873 skip("Failed to create a ddraw object, skipping test.\n");
877 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
878 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
880 memset(&surface_desc
, 0, sizeof(surface_desc
));
881 surface_desc
.dwSize
= sizeof(surface_desc
);
882 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
883 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
884 surface_desc
.dwWidth
= 640;
885 surface_desc
.dwHeight
= 480;
887 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
888 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
890 hr
= IDirectDrawSurface7_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
891 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface3, hr %#x.\n", hr
);
893 hr
= IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d
);
896 skip("Failed to get the IDirect3D7 interface, skipping test.\n");
900 memset(&z_fmt
, 0, sizeof(z_fmt
));
901 hr
= IDirect3D7_EnumZBufferFormats(d3d
, &IID_IDirect3DTnLHalDevice
, enum_z_fmt
, &z_fmt
);
902 if (FAILED(hr
) || !z_fmt
.dwSize
)
904 skip("No depth buffer formats available, skipping test.\n");
908 memset(&surface_desc
, 0, sizeof(surface_desc
));
909 surface_desc
.dwSize
= sizeof(surface_desc
);
910 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
911 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
912 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
913 surface_desc
.dwWidth
= 640;
914 surface_desc
.dwHeight
= 480;
915 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
916 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
920 /* Using a different surface interface version still works */
921 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
922 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
923 refcount
= IDirectDrawSurface7_Release(ds
);
924 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
929 hr
= IDirect3D7_CreateDevice(d3d
, &IID_IDirect3DTnLHalDevice
, (IDirectDrawSurface7
*)surface3
, &device
);
930 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
934 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
935 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
936 color
= get_surface_color(surface
, 320, 240);
937 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
940 if (surface3
) IDirectDrawSurface3_Release(surface3
);
941 if (surface
) IDirectDrawSurface7_Release(surface
);
942 if (device
) IDirect3DDevice7_Release(device
);
943 if (d3d
) IDirect3D7_Release(d3d
);
944 if (ddraw
) IDirectDraw7_Release(ddraw
);
945 DestroyWindow(window
);
948 static void test_coop_level_threaded(void)
950 struct create_window_thread_param p
;
954 if (!(ddraw
= create_ddraw()))
956 skip("Failed to create a ddraw object, skipping test.\n");
959 create_window_thread(&p
);
961 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
962 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
964 IDirectDraw7_Release(ddraw
);
965 destroy_window_thread(&p
);
968 static void test_depth_blit(void)
970 IDirect3DDevice7
*device
;
978 { -1.0, 1.0, 0.50f
, 0xff00ff00},
979 { 1.0, 1.0, 0.50f
, 0xff00ff00},
980 { -1.0, -1.0, 0.50f
, 0xff00ff00},
981 { 1.0, -1.0, 0.50f
, 0xff00ff00},
983 static const D3DCOLOR expected_colors
[4][4] =
985 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
986 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
987 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
988 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
990 DDSURFACEDESC2 ddsd_new
, ddsd_existing
;
992 IDirectDrawSurface7
*ds1
, *ds2
, *ds3
, *rt
;
993 RECT src_rect
, dst_rect
;
1002 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1003 0, 0, 640, 480, 0, 0, 0, 0);
1004 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1006 skip("Failed to create D3D device, skipping test.\n");
1007 DestroyWindow(window
);
1011 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1012 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
1013 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1014 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
1015 IDirect3D7_Release(d3d
);
1017 ds1
= get_depth_stencil(device
);
1019 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1020 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1021 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1022 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1023 hr
= IDirectDrawSurface7_GetSurfaceDesc(ds1
, &ddsd_existing
);
1024 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1025 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1026 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1027 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1028 U4(ddsd_new
).ddpfPixelFormat
= U4(ddsd_existing
).ddpfPixelFormat
;
1029 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1030 ok(SUCCEEDED(hr
), "Failed to create a z buffer, hr %#x.\n", hr
);
1031 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1032 ok(SUCCEEDED(hr
), "Failed to create a z buffer, hr %#x.\n", hr
);
1033 IDirectDraw7_Release(ddraw
);
1035 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1036 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
1037 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1038 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
1039 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
1040 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
1042 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
1043 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
1046 SetRect(&src_rect
, 0, 0, 320, 240);
1047 SetRect(&dst_rect
, 0, 0, 320, 240);
1048 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1049 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1050 /* Different locations. */
1051 SetRect(&src_rect
, 0, 0, 320, 240);
1052 SetRect(&dst_rect
, 320, 240, 640, 480);
1053 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1054 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1056 SetRect(&src_rect
, 0, 0, 320, 240);
1057 SetRect(&dst_rect
, 0, 0, 640, 480);
1058 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1059 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1061 SetRect(&src_rect
, 0, 480, 640, 0);
1062 SetRect(&dst_rect
, 0, 0, 640, 480);
1063 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1064 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1065 SetRect(&src_rect
, 0, 0, 640, 480);
1066 SetRect(&dst_rect
, 0, 480, 640, 0);
1067 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1068 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1069 /* Full, explicit. */
1070 SetRect(&src_rect
, 0, 0, 640, 480);
1071 SetRect(&dst_rect
, 0, 0, 640, 480);
1072 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1073 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1074 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1076 /* Depth blit inside a BeginScene / EndScene pair */
1077 hr
= IDirect3DDevice7_BeginScene(device
);
1078 ok(SUCCEEDED(hr
), "Failed to start scene, hr %#x.\n", hr
);
1079 /* From the current depth stencil */
1080 hr
= IDirectDrawSurface7_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1081 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1082 /* To the current depth stencil */
1083 hr
= IDirectDrawSurface7_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1084 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1085 /* Between unbound surfaces */
1086 hr
= IDirectDrawSurface7_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1087 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1088 hr
= IDirect3DDevice7_EndScene(device
);
1089 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1091 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1092 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1093 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1094 * a reliable result(z = 0.0) */
1095 memset(&fx
, 0, sizeof(fx
));
1096 fx
.dwSize
= sizeof(fx
);
1097 hr
= IDirectDrawSurface7_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1098 ok(SUCCEEDED(hr
), "Failed to clear the source z buffer, hr %#x.\n", hr
);
1100 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
1101 ok(SUCCEEDED(hr
), "Failed to clear the color and z buffers, hr %#x.\n", hr
);
1102 SetRect(&dst_rect
, 0, 0, 320, 240);
1103 hr
= IDirectDrawSurface7_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1104 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1105 IDirectDrawSurface7_Release(ds3
);
1106 IDirectDrawSurface7_Release(ds2
);
1107 IDirectDrawSurface7_Release(ds1
);
1109 hr
= IDirect3DDevice7_BeginScene(device
);
1110 ok(SUCCEEDED(hr
), "Failed to start scene, hr %#x.\n", hr
);
1111 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
1113 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1114 hr
= IDirect3DDevice7_EndScene(device
);
1115 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1117 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1118 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1119 for (i
= 0; i
< 4; ++i
)
1121 for (j
= 0; j
< 4; ++j
)
1123 unsigned int x
= 80 * ((2 * j
) + 1);
1124 unsigned int y
= 60 * ((2 * i
) + 1);
1125 color
= get_surface_color(rt
, x
, y
);
1126 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1127 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1131 IDirectDrawSurface7_Release(rt
);
1132 IDirect3DDevice7_Release(device
);
1133 DestroyWindow(window
);
1136 static void test_texture_load_ckey(void)
1139 IDirect3DDevice7
*device
;
1140 IDirectDraw7
*ddraw
;
1141 IDirectDrawSurface7
*src
;
1142 IDirectDrawSurface7
*dst
;
1143 DDSURFACEDESC2 ddsd
;
1148 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1149 0, 0, 640, 480, 0, 0, 0, 0);
1150 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1152 skip("Failed to create D3D device, skipping test.\n");
1153 DestroyWindow(window
);
1157 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1158 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
1159 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1160 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
1161 IDirect3D7_Release(d3d
);
1163 memset(&ddsd
, 0, sizeof(ddsd
));
1164 ddsd
.dwSize
= sizeof(ddsd
);
1165 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1166 ddsd
.dwHeight
= 128;
1168 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1169 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1170 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1171 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1172 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1173 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1175 /* No surface has a color key */
1176 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1177 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1178 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1179 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1180 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1181 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1182 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1184 /* Source surface has a color key */
1185 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1186 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1187 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1188 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1189 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1190 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1191 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1192 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1193 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1195 /* Both surfaces have a color key: Dest ckey is overwritten */
1196 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1197 hr
= IDirectDrawSurface7_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1198 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1199 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1200 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1201 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1202 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1203 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1204 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1206 /* Only the destination has a color key: It is deleted. This behavior differs from
1207 * IDirect3DTexture(2)::Load */
1208 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1209 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1210 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1211 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1212 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1213 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1214 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1215 todo_wine
ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1217 IDirectDrawSurface7_Release(dst
);
1218 IDirectDrawSurface7_Release(src
);
1219 IDirectDraw7_Release(ddraw
);
1220 IDirect3DDevice7_Release(device
);
1223 static void test_zenable(void)
1227 struct vec4 position
;
1232 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1233 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1234 {{640.0f
, 480.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1235 {{640.0f
, 0.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1237 IDirect3DDevice7
*device
;
1238 IDirectDrawSurface7
*rt
;
1245 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1246 0, 0, 640, 480, 0, 0, 0, 0);
1247 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1249 skip("Failed to create D3D device, skipping test.\n");
1250 DestroyWindow(window
);
1254 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1255 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
1257 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
1258 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1259 hr
= IDirect3DDevice7_BeginScene(device
);
1260 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1261 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
, tquad
, 4, 0);
1262 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1263 hr
= IDirect3DDevice7_EndScene(device
);
1264 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1266 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1267 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1268 for (i
= 0; i
< 4; ++i
)
1270 for (j
= 0; j
< 4; ++j
)
1272 x
= 80 * ((2 * j
) + 1);
1273 y
= 60 * ((2 * i
) + 1);
1274 color
= get_surface_color(rt
, x
, y
);
1275 ok(compare_color(color
, 0x0000ff00, 1),
1276 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1279 IDirectDrawSurface7_Release(rt
);
1281 IDirect3DDevice7_Release(device
);
1282 DestroyWindow(window
);
1285 static void test_ck_rgba(void)
1289 struct vec4 position
;
1290 struct vec2 texcoord
;
1294 {{ 0.0f
, 480.0f
, 0.25f
, 1.0f
}, {0.0f
, 0.0f
}},
1295 {{ 0.0f
, 0.0f
, 0.25f
, 1.0f
}, {0.0f
, 1.0f
}},
1296 {{640.0f
, 480.0f
, 0.25f
, 1.0f
}, {1.0f
, 0.0f
}},
1297 {{640.0f
, 0.0f
, 0.25f
, 1.0f
}, {1.0f
, 1.0f
}},
1298 {{ 0.0f
, 480.0f
, 0.75f
, 1.0f
}, {0.0f
, 0.0f
}},
1299 {{ 0.0f
, 0.0f
, 0.75f
, 1.0f
}, {0.0f
, 1.0f
}},
1300 {{640.0f
, 480.0f
, 0.75f
, 1.0f
}, {1.0f
, 0.0f
}},
1301 {{640.0f
, 0.0f
, 0.75f
, 1.0f
}, {1.0f
, 1.0f
}},
1305 D3DCOLOR fill_color
;
1313 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x000000ff},
1314 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x000000ff},
1315 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00},
1316 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1317 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00807f00},
1318 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x0000ff00},
1319 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00},
1320 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1323 IDirectDrawSurface7
*texture
;
1324 DDSURFACEDESC2 surface_desc
;
1325 IDirect3DDevice7
*device
;
1326 IDirectDrawSurface7
*rt
;
1327 IDirectDraw7
*ddraw
;
1335 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1336 0, 0, 640, 480, 0, 0, 0, 0);
1337 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1339 skip("Failed to create D3D device, skipping test.\n");
1340 DestroyWindow(window
);
1344 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1345 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1346 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1347 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1348 IDirect3D7_Release(d3d
);
1350 memset(&surface_desc
, 0, sizeof(surface_desc
));
1351 surface_desc
.dwSize
= sizeof(surface_desc
);
1352 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1353 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1354 surface_desc
.dwWidth
= 256;
1355 surface_desc
.dwHeight
= 256;
1356 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1357 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1358 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1359 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1360 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1361 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1362 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1363 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1364 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1365 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
1366 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1368 hr
= IDirect3DDevice7_SetTexture(device
, 0, texture
);
1369 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1370 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1371 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1372 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1373 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1375 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1376 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1378 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
1380 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1381 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1382 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1383 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1385 memset(&fx
, 0, sizeof(fx
));
1386 fx
.dwSize
= sizeof(fx
);
1387 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1388 hr
= IDirectDrawSurface7_Blt(texture
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1389 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1391 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
1392 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1393 hr
= IDirect3DDevice7_BeginScene(device
);
1394 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1395 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1396 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1397 hr
= IDirect3DDevice7_EndScene(device
);
1398 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1400 color
= get_surface_color(rt
, 320, 240);
1402 todo_wine
ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1403 tests
[i
].result1
, i
, color
);
1405 ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1406 tests
[i
].result1
, i
, color
);
1408 U5(fx
).dwFillColor
= 0xff0000ff;
1409 hr
= IDirectDrawSurface7_Blt(texture
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1410 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1412 hr
= IDirect3DDevice7_BeginScene(device
);
1413 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1414 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[4], 4, 0);
1415 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1416 hr
= IDirect3DDevice7_EndScene(device
);
1417 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1419 /* This tests that fragments that are masked out by the color key are
1420 * discarded, instead of just fully transparent. */
1421 color
= get_surface_color(rt
, 320, 240);
1423 todo_wine
ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1424 tests
[i
].result2
, i
, color
);
1426 ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1427 tests
[i
].result2
, i
, color
);
1430 IDirectDrawSurface7_Release(rt
);
1431 IDirectDrawSurface7_Release(texture
);
1432 IDirectDraw7_Release(ddraw
);
1433 IDirect3DDevice7_Release(device
);
1434 DestroyWindow(window
);
1439 HMODULE module
= GetModuleHandleA("ddraw.dll");
1441 if (!(pDirectDrawCreateEx
= (void *)GetProcAddress(module
, "DirectDrawCreateEx")))
1443 win_skip("DirectDrawCreateEx not available, skipping tests.\n");
1447 test_process_vertices();
1448 test_coop_level_create_device_window();
1450 test_coop_level_d3d_state();
1451 test_surface_interface_mismatch();
1452 test_coop_level_threaded();
1454 test_texture_load_ckey();