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
21 #include "wine/test.h"
25 static HRESULT (WINAPI
*pDirectDrawCreateEx
)(GUID
*guid
, void **ddraw
, REFIID iid
, IUnknown
*outer_unknown
);
42 struct create_window_thread_param
45 HANDLE window_created
;
46 HANDLE destroy_window
;
50 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
60 if (abs(x
- y
) > ulps
)
66 static BOOL
compare_vec3(struct vec3
*vec
, float x
, float y
, float z
, unsigned int ulps
)
68 return compare_float(vec
->x
, x
, ulps
)
69 && compare_float(vec
->y
, y
, ulps
)
70 && compare_float(vec
->z
, z
, ulps
);
73 static BOOL
compare_vec4(struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
75 return compare_float(vec
->x
, x
, ulps
)
76 && compare_float(vec
->y
, y
, ulps
)
77 && compare_float(vec
->z
, z
, ulps
)
78 && compare_float(vec
->w
, w
, ulps
);
81 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
83 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
85 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
87 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
89 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
93 static DWORD WINAPI
create_window_thread_proc(void *param
)
95 struct create_window_thread_param
*p
= param
;
99 p
->window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
100 0, 0, 640, 480, 0, 0, 0, 0);
101 ret
= SetEvent(p
->window_created
);
102 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
108 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
))
109 DispatchMessage(&msg
);
110 res
= WaitForSingleObject(p
->destroy_window
, 100);
111 if (res
== WAIT_OBJECT_0
)
113 if (res
!= WAIT_TIMEOUT
)
115 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
120 DestroyWindow(p
->window
);
125 static void create_window_thread(struct create_window_thread_param
*p
)
129 p
->window_created
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
130 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
131 p
->destroy_window
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
132 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
133 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
134 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
135 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
136 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
139 static void destroy_window_thread(struct create_window_thread_param
*p
)
141 SetEvent(p
->destroy_window
);
142 WaitForSingleObject(p
->thread
, INFINITE
);
143 CloseHandle(p
->destroy_window
);
144 CloseHandle(p
->window_created
);
145 CloseHandle(p
->thread
);
148 static IDirectDrawSurface7
*get_depth_stencil(IDirect3DDevice7
*device
)
150 IDirectDrawSurface7
*rt
, *ret
;
151 DDSCAPS2 caps
= {DDSCAPS_ZBUFFER
, 0, 0, 0};
154 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
155 ok(SUCCEEDED(hr
), "Failed to get the render target, hr %#x.\n", hr
);
156 hr
= IDirectDrawSurface7_GetAttachedSurface(rt
, &caps
, &ret
);
157 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
158 IDirectDrawSurface7_Release(rt
);
162 static D3DCOLOR
get_surface_color(IDirectDrawSurface7
*surface
, UINT x
, UINT y
)
164 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
165 DDSURFACEDESC2 surface_desc
;
169 memset(&surface_desc
, 0, sizeof(surface_desc
));
170 surface_desc
.dwSize
= sizeof(surface_desc
);
172 hr
= IDirectDrawSurface7_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
, NULL
);
173 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
177 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
179 hr
= IDirectDrawSurface7_Unlock(surface
, &rect
);
180 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
185 static HRESULT CALLBACK
enum_z_fmt(DDPIXELFORMAT
*format
, void *ctx
)
187 DDPIXELFORMAT
*z_fmt
= ctx
;
189 if (U1(*format
).dwZBufferBitDepth
> U1(*z_fmt
).dwZBufferBitDepth
)
195 static IDirectDraw7
*create_ddraw(void)
199 if (FAILED(pDirectDrawCreateEx(NULL
, (void **)&ddraw
, &IID_IDirectDraw7
, NULL
)))
205 static IDirect3DDevice7
*create_device(HWND window
, DWORD coop_level
)
207 IDirectDrawSurface7
*surface
, *ds
;
208 IDirect3DDevice7
*device
= NULL
;
209 DDSURFACEDESC2 surface_desc
;
215 if (!(ddraw
= create_ddraw()))
218 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, coop_level
);
219 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
221 memset(&surface_desc
, 0, sizeof(surface_desc
));
222 surface_desc
.dwSize
= sizeof(surface_desc
);
223 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
224 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
225 surface_desc
.dwWidth
= 640;
226 surface_desc
.dwHeight
= 480;
228 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
229 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
231 if (coop_level
& DDSCL_NORMAL
)
233 IDirectDrawClipper
*clipper
;
235 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
236 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
237 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
238 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
239 hr
= IDirectDrawSurface7_SetClipper(surface
, clipper
);
240 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
241 IDirectDrawClipper_Release(clipper
);
244 hr
= IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d7
);
245 IDirectDraw7_Release(ddraw
);
248 IDirectDrawSurface7_Release(surface
);
252 memset(&z_fmt
, 0, sizeof(z_fmt
));
253 hr
= IDirect3D7_EnumZBufferFormats(d3d7
, &IID_IDirect3DTnLHalDevice
, enum_z_fmt
, &z_fmt
);
254 if (FAILED(hr
) || !z_fmt
.dwSize
)
256 IDirect3D7_Release(d3d7
);
257 IDirectDrawSurface7_Release(surface
);
261 memset(&surface_desc
, 0, sizeof(surface_desc
));
262 surface_desc
.dwSize
= sizeof(surface_desc
);
263 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
264 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
265 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
266 surface_desc
.dwWidth
= 640;
267 surface_desc
.dwHeight
= 480;
268 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
269 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
272 IDirect3D7_Release(d3d7
);
273 IDirectDrawSurface7_Release(surface
);
277 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
278 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
279 IDirectDrawSurface7_Release(ds
);
282 IDirect3D7_Release(d3d7
);
283 IDirectDrawSurface7_Release(surface
);
287 hr
= IDirect3D7_CreateDevice(d3d7
, &IID_IDirect3DTnLHalDevice
, surface
, &device
);
288 IDirect3D7_Release(d3d7
);
289 IDirectDrawSurface7_Release(surface
);
296 static void test_process_vertices(void)
298 IDirect3DVertexBuffer7
*src_vb
, *dst_vb1
, *dst_vb2
;
299 D3DVERTEXBUFFERDESC vb_desc
;
300 IDirect3DDevice7
*device
;
301 struct vec4
*dst_data
;
302 struct vec3
*dst_data2
;
303 struct vec3
*src_data
;
309 static D3DMATRIX world
=
311 0.0f
, 1.0f
, 0.0f
, 0.0f
,
312 1.0f
, 0.0f
, 0.0f
, 0.0f
,
313 0.0f
, 0.0f
, 0.0f
, 1.0f
,
314 0.0f
, 1.0f
, 1.0f
, 1.0f
,
316 static D3DMATRIX view
=
318 2.0f
, 0.0f
, 0.0f
, 0.0f
,
319 0.0f
, -1.0f
, 0.0f
, 0.0f
,
320 0.0f
, 0.0f
, 1.0f
, 0.0f
,
321 0.0f
, 0.0f
, 0.0f
, 3.0f
,
323 static D3DMATRIX proj
=
325 1.0f
, 0.0f
, 0.0f
, 1.0f
,
326 0.0f
, 1.0f
, 1.0f
, 0.0f
,
327 0.0f
, 1.0f
, 1.0f
, 0.0f
,
328 1.0f
, 0.0f
, 0.0f
, 1.0f
,
331 window
= CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW
,
332 0, 0, 640, 480, 0, 0, 0, 0);
333 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
335 skip("Failed to create a ddraw object, skipping test.\n");
336 DestroyWindow(window
);
340 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d7
);
341 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
343 memset(&vb_desc
, 0, sizeof(vb_desc
));
344 vb_desc
.dwSize
= sizeof(vb_desc
);
345 vb_desc
.dwFVF
= D3DFVF_XYZ
;
346 vb_desc
.dwNumVertices
= 4;
347 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &src_vb
, 0);
348 ok(SUCCEEDED(hr
), "Failed to create source vertex buffer, hr %#x.\n", hr
);
350 hr
= IDirect3DVertexBuffer7_Lock(src_vb
, 0, (void **)&src_data
, NULL
);
351 ok(SUCCEEDED(hr
), "Failed to lock source vertex buffer, hr %#x.\n", hr
);
352 src_data
[0].x
= 0.0f
;
353 src_data
[0].y
= 0.0f
;
354 src_data
[0].z
= 0.0f
;
355 src_data
[1].x
= 1.0f
;
356 src_data
[1].y
= 1.0f
;
357 src_data
[1].z
= 1.0f
;
358 src_data
[2].x
= -1.0f
;
359 src_data
[2].y
= -1.0f
;
360 src_data
[2].z
= 0.5f
;
361 src_data
[3].x
= 0.5f
;
362 src_data
[3].y
= -0.5f
;
363 src_data
[3].z
= 0.25f
;
364 hr
= IDirect3DVertexBuffer7_Unlock(src_vb
);
365 ok(SUCCEEDED(hr
), "Failed to unlock source vertex buffer, hr %#x.\n", hr
);
367 memset(&vb_desc
, 0, sizeof(vb_desc
));
368 vb_desc
.dwSize
= sizeof(vb_desc
);
369 vb_desc
.dwFVF
= D3DFVF_XYZRHW
;
370 vb_desc
.dwNumVertices
= 4;
371 /* MSDN says that the last parameter must be 0 - check that. */
372 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &dst_vb1
, 4);
373 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
375 memset(&vb_desc
, 0, sizeof(vb_desc
));
376 vb_desc
.dwSize
= sizeof(vb_desc
);
377 vb_desc
.dwFVF
= D3DFVF_XYZ
;
378 vb_desc
.dwNumVertices
= 5;
379 /* MSDN says that the last parameter must be 0 - check that. */
380 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &dst_vb2
, 12345678);
381 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
383 memset(&vp
, 0, sizeof(vp
));
390 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
391 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
393 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
394 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
395 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb2
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
396 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
398 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
399 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
400 ok(compare_vec4(&dst_data
[0], +1.280e+2f
, +1.280e+2f
, +0.000e+0f
, +1.000e+0f
, 4096),
401 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
402 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
403 ok(compare_vec4(&dst_data
[1], +1.920e+2f
, +6.400e+1f
, +1.000e+0f
, +1.000e+0f
, 4096),
404 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
405 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
406 ok(compare_vec4(&dst_data
[2], +6.400e+1f
, +1.920e+2f
, +5.000e-1f
, +1.000e+0f
, 4096),
407 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
408 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
409 ok(compare_vec4(&dst_data
[3], +1.600e+2f
, +1.600e+2f
, +2.500e-1f
, +1.000e+0f
, 4096),
410 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
411 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
412 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
413 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
415 hr
= IDirect3DVertexBuffer7_Lock(dst_vb2
, 0, (void **)&dst_data2
, NULL
);
416 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
417 /* Small thing without much practical meaning, but I stumbled upon it,
418 * so let's check for it: If the output vertex buffer has no RHW value,
419 * the RHW value of the last vertex is written into the next vertex. */
420 ok(compare_vec3(&dst_data2
[4], +1.000e+0f
, +0.000e+0f
, +0.000e+0f
, 4096),
421 "Got unexpected vertex 4 {%.8e, %.8e, %.8e}.\n",
422 dst_data2
[4].x
, dst_data2
[4].y
, dst_data2
[4].z
);
423 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb2
);
424 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
426 /* Try a more complicated viewport, same vertices. */
427 memset(&vp
, 0, sizeof(vp
));
434 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
435 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
437 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
438 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
440 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
441 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
442 ok(compare_vec4(&dst_data
[0], +1.330e+2f
, +7.000e+1f
, -2.000e+0f
, +1.000e+0f
, 4096),
443 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
444 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
445 ok(compare_vec4(&dst_data
[1], +2.560e+2f
, +5.000e+0f
, +4.000e+0f
, +1.000e+0f
, 4096),
446 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
447 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
448 ok(compare_vec4(&dst_data
[2], +1.000e+1f
, +1.350e+2f
, +1.000e+0f
, +1.000e+0f
, 4096),
449 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
450 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
451 ok(compare_vec4(&dst_data
[3], +1.945e+2f
, +1.025e+2f
, -5.000e-1f
, +1.000e+0f
, 4096),
452 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
453 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
454 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
455 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
457 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &world
);
458 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
459 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &view
);
460 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
461 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &proj
);
462 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
464 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
465 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
467 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
468 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
469 ok(compare_vec4(&dst_data
[0], +2.560e+2f
, +7.000e+1f
, -2.000e+0f
, +3.333e-1f
, 4096),
470 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
471 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
472 ok(compare_vec4(&dst_data
[1], +2.560e+2f
, +7.813e+1f
, -2.750e+0f
, +1.250e-1f
, 4096),
473 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
474 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
475 ok(compare_vec4(&dst_data
[2], +2.560e+2f
, +4.400e+1f
, +4.000e-1f
, +4.000e-1f
, 4096),
476 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
477 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
478 ok(compare_vec4(&dst_data
[3], +2.560e+2f
, +8.182e+1f
, -3.091e+0f
, +3.636e-1f
, 4096),
479 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
480 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
481 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
482 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
484 IDirect3DVertexBuffer7_Release(dst_vb2
);
485 IDirect3DVertexBuffer7_Release(dst_vb1
);
486 IDirect3DVertexBuffer7_Release(src_vb
);
487 IDirect3D7_Release(d3d7
);
488 IDirect3DDevice7_Release(device
);
489 DestroyWindow(window
);
492 static void test_coop_level_create_device_window(void)
494 HWND focus_window
, device_window
;
498 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
499 0, 0, 640, 480, 0, 0, 0, 0);
500 if (!(ddraw
= create_ddraw()))
502 skip("Failed to create a 3D device, skipping test.\n");
503 DestroyWindow(focus_window
);
507 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
508 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
509 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
510 ok(!device_window
, "Unexpected device window found.\n");
511 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
512 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
513 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
514 ok(!device_window
, "Unexpected device window found.\n");
515 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
516 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
517 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
518 ok(!device_window
, "Unexpected device window found.\n");
519 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
520 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
521 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
522 ok(!device_window
, "Unexpected device window found.\n");
523 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
524 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
525 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
526 ok(!device_window
, "Unexpected device window found.\n");
528 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
529 if (broken(hr
== DDERR_INVALIDPARAMS
))
531 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
532 IDirectDraw7_Release(ddraw
);
533 DestroyWindow(focus_window
);
537 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
538 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
539 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
540 ok(!device_window
, "Unexpected device window found.\n");
541 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
542 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
543 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
544 ok(!device_window
, "Unexpected device window found.\n");
546 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
547 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
548 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
549 ok(!device_window
, "Unexpected device window found.\n");
550 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
551 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
552 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
553 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
554 ok(!!device_window
, "Device window not found.\n");
556 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
557 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
558 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
559 ok(!device_window
, "Unexpected device window found.\n");
560 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
561 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
562 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
563 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
564 ok(!!device_window
, "Device window not found.\n");
566 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
567 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
568 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
569 ok(!device_window
, "Unexpected device window found.\n");
570 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
571 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
572 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
573 ok(!device_window
, "Unexpected device window found.\n");
574 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
575 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
576 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
577 ok(!device_window
, "Unexpected device window found.\n");
578 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
579 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
580 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
581 ok(!!device_window
, "Device window not found.\n");
583 IDirectDraw7_Release(ddraw
);
584 DestroyWindow(focus_window
);
587 static void test_clipper_blt(void)
589 IDirectDrawSurface7
*src_surface
, *dst_surface
;
590 RECT client_rect
, src_rect
, *rect
;
591 IDirectDrawClipper
*clipper
;
592 DDSURFACEDESC2 surface_desc
;
593 unsigned int i
, j
, x
, y
;
604 static const DWORD src_data
[] =
606 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
607 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
608 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
610 static const D3DCOLOR expected1
[] =
612 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
613 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
614 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
615 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
617 static const D3DCOLOR expected2
[] =
619 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
620 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
621 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
622 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
625 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
626 10, 10, 640, 480, 0, 0, 0, 0);
627 ShowWindow(window
, SW_SHOW
);
628 if (!(ddraw
= create_ddraw()))
630 skip("Failed to create a ddraw object, skipping test.\n");
631 DestroyWindow(window
);
635 ret
= GetClientRect(window
, &client_rect
);
636 ok(ret
, "Failed to get client rect.\n");
637 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
638 ok(ret
, "Failed to map client rect.\n");
640 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
641 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
643 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
644 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
645 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
646 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
647 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
648 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
649 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
650 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
651 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
652 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
653 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
654 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
655 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
656 ok(rgn_data
->rdh
.nCount
== 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
657 ok(rgn_data
->rdh
.nRgnSize
== 16, "Got unexpected region size %u.\n", rgn_data
->rdh
.nRgnSize
);
658 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
659 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
660 rgn_data
->rdh
.rcBound
.left
, rgn_data
->rdh
.rcBound
.top
,
661 rgn_data
->rdh
.rcBound
.right
, rgn_data
->rdh
.rcBound
.bottom
,
662 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
663 rect
= (RECT
*)&rgn_data
->Buffer
[0];
664 ok(EqualRect(rect
, &client_rect
),
665 "Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
666 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
667 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
668 HeapFree(GetProcessHeap(), 0, rgn_data
);
670 r1
= CreateRectRgn(0, 0, 320, 240);
671 ok(!!r1
, "Failed to create region.\n");
672 r2
= CreateRectRgn(320, 240, 640, 480);
673 ok(!!r2
, "Failed to create region.\n");
674 CombineRgn(r1
, r1
, r2
, RGN_OR
);
675 ret
= GetRegionData(r1
, 0, NULL
);
676 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
677 ret
= GetRegionData(r1
, ret
, rgn_data
);
678 ok(!!ret
, "Failed to get region data.\n");
683 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
684 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
685 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
686 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
687 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
688 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
690 HeapFree(GetProcessHeap(), 0, rgn_data
);
692 memset(&surface_desc
, 0, sizeof(surface_desc
));
693 surface_desc
.dwSize
= sizeof(surface_desc
);
694 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
695 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
696 surface_desc
.dwWidth
= 640;
697 surface_desc
.dwHeight
= 480;
698 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
699 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
700 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
701 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
702 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
703 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
705 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
706 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
707 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
708 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
710 memset(&fx
, 0, sizeof(fx
));
711 fx
.dwSize
= sizeof(fx
);
712 hr
= IDirectDrawSurface7_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
713 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
714 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
715 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
717 hr
= IDirectDrawSurface7_Lock(src_surface
, NULL
, &surface_desc
, 0, NULL
);
718 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
719 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
720 ptr
= surface_desc
.lpSurface
;
721 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
722 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
723 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
724 hr
= IDirectDrawSurface7_Unlock(src_surface
, NULL
);
725 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
727 hr
= IDirectDrawSurface7_SetClipper(dst_surface
, clipper
);
728 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
730 SetRect(&src_rect
, 1, 1, 5, 2);
731 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
732 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
733 for (i
= 0; i
< 4; ++i
)
735 for (j
= 0; j
< 4; ++j
)
737 x
= 80 * ((2 * j
) + 1);
738 y
= 60 * ((2 * i
) + 1);
739 color
= get_surface_color(dst_surface
, x
, y
);
740 ok(compare_color(color
, expected1
[i
* 4 + j
], 1),
741 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
745 U5(fx
).dwFillColor
= 0xff0000ff;
746 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
747 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
748 for (i
= 0; i
< 4; ++i
)
750 for (j
= 0; j
< 4; ++j
)
752 x
= 80 * ((2 * j
) + 1);
753 y
= 60 * ((2 * i
) + 1);
754 color
= get_surface_color(dst_surface
, x
, y
);
755 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
756 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
760 hr
= IDirectDrawSurface7_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
761 ok(hr
== DDERR_BLTFASTCANTCLIP
, "Got unexpected hr %#x.\n", hr
);
763 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
764 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
765 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
766 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
767 DestroyWindow(window
);
768 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
769 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
770 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
771 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
772 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
773 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
774 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
775 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
776 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
777 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
778 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
779 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
781 IDirectDrawSurface7_Release(dst_surface
);
782 IDirectDrawSurface7_Release(src_surface
);
783 IDirectDrawClipper_Release(clipper
);
784 IDirectDraw7_Release(ddraw
);
787 static void test_coop_level_d3d_state(void)
789 IDirectDrawSurface7
*rt
, *surface
;
790 IDirect3DDevice7
*device
;
798 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
799 0, 0, 640, 480, 0, 0, 0, 0);
800 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
802 skip("Failed to create D3D device, skipping test.\n");
803 DestroyWindow(window
);
807 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
808 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
809 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
810 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
811 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
812 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
813 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
814 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
815 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
816 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
817 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
818 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
819 color
= get_surface_color(rt
, 320, 240);
820 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
822 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
823 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
824 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
825 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
826 IDirect3D7_Release(d3d
);
827 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
828 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
829 hr
= IDirectDrawSurface7_IsLost(rt
);
830 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
831 hr
= IDirectDraw7_RestoreAllSurfaces(ddraw
);
832 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
833 IDirectDraw7_Release(ddraw
);
835 hr
= IDirect3DDevice7_GetRenderTarget(device
, &surface
);
836 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
837 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
838 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
839 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
840 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
841 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
842 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
843 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
844 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
845 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
846 color
= get_surface_color(rt
, 320, 240);
847 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
849 IDirectDrawSurface7_Release(surface
);
850 IDirectDrawSurface7_Release(rt
);
851 IDirect3DDevice7_Release(device
);
852 DestroyWindow(window
);
855 static void test_surface_interface_mismatch(void)
857 IDirectDraw7
*ddraw
= NULL
;
858 IDirect3D7
*d3d
= NULL
;
859 IDirectDrawSurface7
*surface
= NULL
, *ds
;
860 IDirectDrawSurface3
*surface3
= NULL
;
861 IDirect3DDevice7
*device
= NULL
;
862 DDSURFACEDESC2 surface_desc
;
869 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
870 0, 0, 640, 480, 0, 0, 0, 0);
872 if (!(ddraw
= create_ddraw()))
874 skip("Failed to create a ddraw object, skipping test.\n");
878 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
879 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
881 memset(&surface_desc
, 0, sizeof(surface_desc
));
882 surface_desc
.dwSize
= sizeof(surface_desc
);
883 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
884 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
885 surface_desc
.dwWidth
= 640;
886 surface_desc
.dwHeight
= 480;
888 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
889 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
891 hr
= IDirectDrawSurface7_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
892 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface3, hr %#x.\n", hr
);
894 hr
= IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d
);
897 skip("Failed to get the IDirect3D7 interface, skipping test.\n");
901 memset(&z_fmt
, 0, sizeof(z_fmt
));
902 hr
= IDirect3D7_EnumZBufferFormats(d3d
, &IID_IDirect3DTnLHalDevice
, enum_z_fmt
, &z_fmt
);
903 if (FAILED(hr
) || !z_fmt
.dwSize
)
905 skip("No depth buffer formats available, skipping test.\n");
909 memset(&surface_desc
, 0, sizeof(surface_desc
));
910 surface_desc
.dwSize
= sizeof(surface_desc
);
911 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
912 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
913 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
914 surface_desc
.dwWidth
= 640;
915 surface_desc
.dwHeight
= 480;
916 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
917 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
921 /* Using a different surface interface version still works */
922 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
923 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
924 refcount
= IDirectDrawSurface7_Release(ds
);
925 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
930 hr
= IDirect3D7_CreateDevice(d3d
, &IID_IDirect3DTnLHalDevice
, (IDirectDrawSurface7
*)surface3
, &device
);
931 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
935 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
936 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
937 color
= get_surface_color(surface
, 320, 240);
938 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
941 if (surface3
) IDirectDrawSurface3_Release(surface3
);
942 if (surface
) IDirectDrawSurface7_Release(surface
);
943 if (device
) IDirect3DDevice7_Release(device
);
944 if (d3d
) IDirect3D7_Release(d3d
);
945 if (ddraw
) IDirectDraw7_Release(ddraw
);
946 DestroyWindow(window
);
949 static void test_coop_level_threaded(void)
951 struct create_window_thread_param p
;
955 if (!(ddraw
= create_ddraw()))
957 skip("Failed to create a ddraw object, skipping test.\n");
960 create_window_thread(&p
);
962 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
963 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
965 IDirectDraw7_Release(ddraw
);
966 destroy_window_thread(&p
);
969 static void test_depth_blit(void)
971 IDirect3DDevice7
*device
;
979 { -1.0, 1.0, 0.50f
, 0xff00ff00},
980 { 1.0, 1.0, 0.50f
, 0xff00ff00},
981 { -1.0, -1.0, 0.50f
, 0xff00ff00},
982 { 1.0, -1.0, 0.50f
, 0xff00ff00},
984 static const D3DCOLOR expected_colors
[4][4] =
986 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
987 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
988 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
989 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
991 DDSURFACEDESC2 ddsd_new
, ddsd_existing
;
993 IDirectDrawSurface7
*ds1
, *ds2
, *ds3
, *rt
;
994 RECT src_rect
, dst_rect
;
1003 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1004 0, 0, 640, 480, 0, 0, 0, 0);
1005 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1007 skip("Failed to create D3D device, skipping test.\n");
1008 DestroyWindow(window
);
1012 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1013 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
1014 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1015 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
1016 IDirect3D7_Release(d3d
);
1018 ds1
= get_depth_stencil(device
);
1020 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1021 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1022 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1023 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1024 hr
= IDirectDrawSurface7_GetSurfaceDesc(ds1
, &ddsd_existing
);
1025 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1026 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1027 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1028 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1029 U4(ddsd_new
).ddpfPixelFormat
= U4(ddsd_existing
).ddpfPixelFormat
;
1030 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1031 ok(SUCCEEDED(hr
), "Failed to create a z buffer, hr %#x.\n", hr
);
1032 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1033 ok(SUCCEEDED(hr
), "Failed to create a z buffer, hr %#x.\n", hr
);
1034 IDirectDraw7_Release(ddraw
);
1036 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1037 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
1038 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1039 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
1040 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
1041 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
1043 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
1044 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
1047 SetRect(&src_rect
, 0, 0, 320, 240);
1048 SetRect(&dst_rect
, 0, 0, 320, 240);
1049 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1050 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1051 /* Different locations. */
1052 SetRect(&src_rect
, 0, 0, 320, 240);
1053 SetRect(&dst_rect
, 320, 240, 640, 480);
1054 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1055 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1057 SetRect(&src_rect
, 0, 0, 320, 240);
1058 SetRect(&dst_rect
, 0, 0, 640, 480);
1059 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1060 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1062 SetRect(&src_rect
, 0, 480, 640, 0);
1063 SetRect(&dst_rect
, 0, 0, 640, 480);
1064 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1065 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1066 SetRect(&src_rect
, 0, 0, 640, 480);
1067 SetRect(&dst_rect
, 0, 480, 640, 0);
1068 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1069 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1070 /* Full, explicit. */
1071 SetRect(&src_rect
, 0, 0, 640, 480);
1072 SetRect(&dst_rect
, 0, 0, 640, 480);
1073 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1074 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1075 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1077 /* Depth blit inside a BeginScene / EndScene pair */
1078 hr
= IDirect3DDevice7_BeginScene(device
);
1079 ok(SUCCEEDED(hr
), "Failed to start scene, hr %#x.\n", hr
);
1080 /* From the current depth stencil */
1081 hr
= IDirectDrawSurface7_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1082 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1083 /* To the current depth stencil */
1084 hr
= IDirectDrawSurface7_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1085 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1086 /* Between unbound surfaces */
1087 hr
= IDirectDrawSurface7_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1088 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1089 hr
= IDirect3DDevice7_EndScene(device
);
1090 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1092 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1093 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1094 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1095 * a reliable result(z = 0.0) */
1096 memset(&fx
, 0, sizeof(fx
));
1097 fx
.dwSize
= sizeof(fx
);
1098 hr
= IDirectDrawSurface7_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1099 ok(SUCCEEDED(hr
), "Failed to clear the source z buffer, hr %#x.\n", hr
);
1101 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
1102 ok(SUCCEEDED(hr
), "Failed to clear the color and z buffers, hr %#x.\n", hr
);
1103 SetRect(&dst_rect
, 0, 0, 320, 240);
1104 hr
= IDirectDrawSurface7_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1105 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1106 IDirectDrawSurface7_Release(ds3
);
1107 IDirectDrawSurface7_Release(ds2
);
1108 IDirectDrawSurface7_Release(ds1
);
1110 hr
= IDirect3DDevice7_BeginScene(device
);
1111 ok(SUCCEEDED(hr
), "Failed to start scene, hr %#x.\n", hr
);
1112 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
1114 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1115 hr
= IDirect3DDevice7_EndScene(device
);
1116 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1118 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1119 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1120 for (i
= 0; i
< 4; ++i
)
1122 for (j
= 0; j
< 4; ++j
)
1124 unsigned int x
= 80 * ((2 * j
) + 1);
1125 unsigned int y
= 60 * ((2 * i
) + 1);
1126 color
= get_surface_color(rt
, x
, y
);
1127 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1128 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1132 IDirectDrawSurface7_Release(rt
);
1133 IDirect3DDevice7_Release(device
);
1134 DestroyWindow(window
);
1137 static void test_texture_load_ckey(void)
1140 IDirect3DDevice7
*device
;
1141 IDirectDraw7
*ddraw
;
1142 IDirectDrawSurface7
*src
;
1143 IDirectDrawSurface7
*dst
;
1144 DDSURFACEDESC2 ddsd
;
1149 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1150 0, 0, 640, 480, 0, 0, 0, 0);
1151 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1153 skip("Failed to create D3D device, skipping test.\n");
1154 DestroyWindow(window
);
1158 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1159 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
1160 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1161 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
1162 IDirect3D7_Release(d3d
);
1164 memset(&ddsd
, 0, sizeof(ddsd
));
1165 ddsd
.dwSize
= sizeof(ddsd
);
1166 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1167 ddsd
.dwHeight
= 128;
1169 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1170 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1171 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1172 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1173 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1174 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1176 /* No surface has a color key */
1177 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1178 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1179 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1180 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1181 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1182 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1183 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1185 /* Source surface has a color key */
1186 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1187 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1188 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1189 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1190 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1191 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1192 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1193 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1194 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1196 /* Both surfaces have a color key: Dest ckey is overwritten */
1197 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1198 hr
= IDirectDrawSurface7_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1199 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1200 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1201 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1202 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1203 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1204 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1205 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1207 /* Only the destination has a color key: It is deleted. This behavior differs from
1208 * IDirect3DTexture(2)::Load */
1209 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1210 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1211 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1212 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1213 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1214 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1215 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1216 todo_wine
ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1218 IDirectDrawSurface7_Release(dst
);
1219 IDirectDrawSurface7_Release(src
);
1220 IDirectDraw7_Release(ddraw
);
1221 IDirect3DDevice7_Release(device
);
1224 static void test_zenable(void)
1228 struct vec4 position
;
1233 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1234 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1235 {{640.0f
, 480.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1236 {{640.0f
, 0.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1238 IDirect3DDevice7
*device
;
1239 IDirectDrawSurface7
*rt
;
1246 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1247 0, 0, 640, 480, 0, 0, 0, 0);
1248 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1250 skip("Failed to create D3D device, skipping test.\n");
1251 DestroyWindow(window
);
1255 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1256 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
1258 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
1259 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1260 hr
= IDirect3DDevice7_BeginScene(device
);
1261 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1262 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
, tquad
, 4, 0);
1263 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1264 hr
= IDirect3DDevice7_EndScene(device
);
1265 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1267 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1268 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1269 for (i
= 0; i
< 4; ++i
)
1271 for (j
= 0; j
< 4; ++j
)
1273 x
= 80 * ((2 * j
) + 1);
1274 y
= 60 * ((2 * i
) + 1);
1275 color
= get_surface_color(rt
, x
, y
);
1276 ok(compare_color(color
, 0x0000ff00, 1),
1277 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1280 IDirectDrawSurface7_Release(rt
);
1282 IDirect3DDevice7_Release(device
);
1283 DestroyWindow(window
);
1286 static void test_ck_rgba(void)
1290 struct vec4 position
;
1291 struct vec2 texcoord
;
1295 {{ 0.0f
, 480.0f
, 0.25f
, 1.0f
}, {0.0f
, 0.0f
}},
1296 {{ 0.0f
, 0.0f
, 0.25f
, 1.0f
}, {0.0f
, 1.0f
}},
1297 {{640.0f
, 480.0f
, 0.25f
, 1.0f
}, {1.0f
, 0.0f
}},
1298 {{640.0f
, 0.0f
, 0.25f
, 1.0f
}, {1.0f
, 1.0f
}},
1299 {{ 0.0f
, 480.0f
, 0.75f
, 1.0f
}, {0.0f
, 0.0f
}},
1300 {{ 0.0f
, 0.0f
, 0.75f
, 1.0f
}, {0.0f
, 1.0f
}},
1301 {{640.0f
, 480.0f
, 0.75f
, 1.0f
}, {1.0f
, 0.0f
}},
1302 {{640.0f
, 0.0f
, 0.75f
, 1.0f
}, {1.0f
, 1.0f
}},
1306 D3DCOLOR fill_color
;
1314 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x000000ff},
1315 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x000000ff},
1316 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00},
1317 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1318 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00807f00},
1319 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x0000ff00},
1320 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00},
1321 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1324 IDirectDrawSurface7
*texture
;
1325 DDSURFACEDESC2 surface_desc
;
1326 IDirect3DDevice7
*device
;
1327 IDirectDrawSurface7
*rt
;
1328 IDirectDraw7
*ddraw
;
1336 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1337 0, 0, 640, 480, 0, 0, 0, 0);
1338 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1340 skip("Failed to create D3D device, skipping test.\n");
1341 DestroyWindow(window
);
1345 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1346 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1347 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1348 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1349 IDirect3D7_Release(d3d
);
1351 memset(&surface_desc
, 0, sizeof(surface_desc
));
1352 surface_desc
.dwSize
= sizeof(surface_desc
);
1353 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1354 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1355 surface_desc
.dwWidth
= 256;
1356 surface_desc
.dwHeight
= 256;
1357 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1358 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1359 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1360 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1361 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1362 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1363 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1364 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1365 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1366 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
1367 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1369 hr
= IDirect3DDevice7_SetTexture(device
, 0, texture
);
1370 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1371 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1372 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1373 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1374 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1376 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1377 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1379 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
1381 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1382 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1383 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1384 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1386 memset(&fx
, 0, sizeof(fx
));
1387 fx
.dwSize
= sizeof(fx
);
1388 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1389 hr
= IDirectDrawSurface7_Blt(texture
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1390 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1392 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
1393 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1394 hr
= IDirect3DDevice7_BeginScene(device
);
1395 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1396 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1397 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1398 hr
= IDirect3DDevice7_EndScene(device
);
1399 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1401 color
= get_surface_color(rt
, 320, 240);
1403 todo_wine
ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1404 tests
[i
].result1
, i
, color
);
1406 ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1407 tests
[i
].result1
, i
, color
);
1409 U5(fx
).dwFillColor
= 0xff0000ff;
1410 hr
= IDirectDrawSurface7_Blt(texture
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1411 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1413 hr
= IDirect3DDevice7_BeginScene(device
);
1414 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1415 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[4], 4, 0);
1416 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1417 hr
= IDirect3DDevice7_EndScene(device
);
1418 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1420 /* This tests that fragments that are masked out by the color key are
1421 * discarded, instead of just fully transparent. */
1422 color
= get_surface_color(rt
, 320, 240);
1424 todo_wine
ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1425 tests
[i
].result2
, i
, color
);
1427 ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1428 tests
[i
].result2
, i
, color
);
1431 IDirectDrawSurface7_Release(rt
);
1432 IDirectDrawSurface7_Release(texture
);
1433 IDirectDraw7_Release(ddraw
);
1434 IDirect3DDevice7_Release(device
);
1435 DestroyWindow(window
);
1441 REFIID refcount_iid
;
1445 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
1446 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
1448 ULONG refcount
, expected_refcount
;
1449 IUnknown
*iface1
, *iface2
;
1453 for (i
= 0; i
< entry_count
; ++i
)
1455 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
1456 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
1459 for (j
= 0; j
< entry_count
; ++j
)
1461 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
1462 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
1465 expected_refcount
= 0;
1466 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
1467 ++expected_refcount
;
1468 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
1469 ++expected_refcount
;
1470 refcount
= IUnknown_Release(iface2
);
1471 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
1472 refcount
, test_name
, i
, j
, expected_refcount
);
1476 expected_refcount
= 0;
1477 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
1478 ++expected_refcount
;
1479 refcount
= IUnknown_Release(iface1
);
1480 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
1481 refcount
, test_name
, i
, expected_refcount
);
1486 static void test_surface_qi(void)
1488 static const struct qi_test tests
[] =
1490 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
1491 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
1492 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
1493 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1494 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
1495 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
1496 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
1497 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
1498 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
1499 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
1500 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
1501 {&IID_IDirect3DDevice2
, NULL
, E_NOINTERFACE
},
1502 {&IID_IDirect3DDevice
, NULL
, E_NOINTERFACE
},
1503 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
1504 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
1505 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
1506 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
1507 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
1508 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
1509 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
1510 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
1511 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
1512 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
1513 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
1514 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
1515 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
1516 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
1517 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
1518 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
1519 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
1520 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
1521 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
1522 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
1523 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
1524 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
1525 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
1526 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
1527 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
1528 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
1529 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
1530 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
1531 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
1534 IDirectDrawSurface7
*surface
;
1535 DDSURFACEDESC2 surface_desc
;
1536 IDirect3DDevice7
*device
;
1537 IDirectDraw7
*ddraw
;
1541 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1542 0, 0, 640, 480, 0, 0, 0, 0);
1543 /* Try to create a D3D device to see if the ddraw implementation supports
1544 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
1545 * doesn't support e.g. the IDirect3DTexture interfaces. */
1546 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1548 skip("Failed to create D3D device, skipping test.\n");
1549 DestroyWindow(window
);
1552 IDirect3DDevice_Release(device
);
1553 if (!(ddraw
= create_ddraw()))
1555 skip("Failed to create a ddraw object, skipping test.\n");
1556 DestroyWindow(window
);
1559 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1560 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1562 memset(&surface_desc
, 0, sizeof(surface_desc
));
1563 surface_desc
.dwSize
= sizeof(surface_desc
);
1564 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1565 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1566 surface_desc
.dwWidth
= 512;
1567 surface_desc
.dwHeight
= 512;
1568 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1569 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1571 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface7
, tests
, sizeof(tests
) / sizeof(*tests
));
1573 IDirectDrawSurface7_Release(surface
);
1574 IDirectDraw7_Release(ddraw
);
1575 DestroyWindow(window
);
1578 static void test_device_qi(void)
1580 static const struct qi_test tests
[] =
1582 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
1583 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
1584 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
1585 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1586 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
1587 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
1588 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
1589 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
1590 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
1591 {&IID_IDirect3DDevice7
, &IID_IDirect3DDevice7
, S_OK
},
1592 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
1593 {&IID_IDirect3DDevice2
, NULL
, E_NOINTERFACE
},
1594 {&IID_IDirect3DDevice
, NULL
, E_NOINTERFACE
},
1595 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
1596 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
1597 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
1598 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
1599 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
1600 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
1601 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
1602 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
1603 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
1604 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
1605 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
1606 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
1607 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
1608 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
1609 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
1610 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
1611 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
1612 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
1613 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
1614 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
1615 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
1616 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
1617 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
1618 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
1619 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
1620 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
1621 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
1622 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
1623 {&IID_IUnknown
, &IID_IDirect3DDevice7
, S_OK
},
1626 IDirect3DDevice7
*device
;
1629 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1630 0, 0, 640, 480, 0, 0, 0, 0);
1631 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1633 skip("Failed to create D3D device, skipping test.\n");
1634 DestroyWindow(window
);
1638 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice7
, tests
, sizeof(tests
) / sizeof(*tests
));
1640 IDirect3DDevice7_Release(device
);
1641 DestroyWindow(window
);
1646 HMODULE module
= GetModuleHandleA("ddraw.dll");
1648 if (!(pDirectDrawCreateEx
= (void *)GetProcAddress(module
, "DirectDrawCreateEx")))
1650 win_skip("DirectDrawCreateEx not available, skipping tests.\n");
1654 test_process_vertices();
1655 test_coop_level_create_device_window();
1657 test_coop_level_d3d_state();
1658 test_surface_interface_mismatch();
1659 test_coop_level_threaded();
1661 test_texture_load_ckey();