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 const UINT
*expect_messages
;
298 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
300 if (expect_messages
&& message
== *expect_messages
)
303 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
306 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
307 * interface. This prevents subsequent SetCooperativeLevel() calls on a
308 * different window from failing with DDERR_HWNDALREADYSET. */
309 static void fix_wndproc(HWND window
, LONG_PTR proc
)
314 if (!(ddraw
= create_ddraw()))
317 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
318 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
319 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
320 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
321 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
323 IDirectDraw7_Release(ddraw
);
326 static void test_process_vertices(void)
328 IDirect3DVertexBuffer7
*src_vb
, *dst_vb1
, *dst_vb2
;
329 D3DVERTEXBUFFERDESC vb_desc
;
330 IDirect3DDevice7
*device
;
331 struct vec4
*dst_data
;
332 struct vec3
*dst_data2
;
333 struct vec3
*src_data
;
339 static D3DMATRIX world
=
341 0.0f
, 1.0f
, 0.0f
, 0.0f
,
342 1.0f
, 0.0f
, 0.0f
, 0.0f
,
343 0.0f
, 0.0f
, 0.0f
, 1.0f
,
344 0.0f
, 1.0f
, 1.0f
, 1.0f
,
346 static D3DMATRIX view
=
348 2.0f
, 0.0f
, 0.0f
, 0.0f
,
349 0.0f
, -1.0f
, 0.0f
, 0.0f
,
350 0.0f
, 0.0f
, 1.0f
, 0.0f
,
351 0.0f
, 0.0f
, 0.0f
, 3.0f
,
353 static D3DMATRIX proj
=
355 1.0f
, 0.0f
, 0.0f
, 1.0f
,
356 0.0f
, 1.0f
, 1.0f
, 0.0f
,
357 0.0f
, 1.0f
, 1.0f
, 0.0f
,
358 1.0f
, 0.0f
, 0.0f
, 1.0f
,
361 window
= CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW
,
362 0, 0, 640, 480, 0, 0, 0, 0);
363 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
365 skip("Failed to create a ddraw object, skipping test.\n");
366 DestroyWindow(window
);
370 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d7
);
371 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
373 memset(&vb_desc
, 0, sizeof(vb_desc
));
374 vb_desc
.dwSize
= sizeof(vb_desc
);
375 vb_desc
.dwFVF
= D3DFVF_XYZ
;
376 vb_desc
.dwNumVertices
= 4;
377 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &src_vb
, 0);
378 ok(SUCCEEDED(hr
), "Failed to create source vertex buffer, hr %#x.\n", hr
);
380 hr
= IDirect3DVertexBuffer7_Lock(src_vb
, 0, (void **)&src_data
, NULL
);
381 ok(SUCCEEDED(hr
), "Failed to lock source vertex buffer, hr %#x.\n", hr
);
382 src_data
[0].x
= 0.0f
;
383 src_data
[0].y
= 0.0f
;
384 src_data
[0].z
= 0.0f
;
385 src_data
[1].x
= 1.0f
;
386 src_data
[1].y
= 1.0f
;
387 src_data
[1].z
= 1.0f
;
388 src_data
[2].x
= -1.0f
;
389 src_data
[2].y
= -1.0f
;
390 src_data
[2].z
= 0.5f
;
391 src_data
[3].x
= 0.5f
;
392 src_data
[3].y
= -0.5f
;
393 src_data
[3].z
= 0.25f
;
394 hr
= IDirect3DVertexBuffer7_Unlock(src_vb
);
395 ok(SUCCEEDED(hr
), "Failed to unlock source vertex buffer, hr %#x.\n", hr
);
397 memset(&vb_desc
, 0, sizeof(vb_desc
));
398 vb_desc
.dwSize
= sizeof(vb_desc
);
399 vb_desc
.dwFVF
= D3DFVF_XYZRHW
;
400 vb_desc
.dwNumVertices
= 4;
401 /* MSDN says that the last parameter must be 0 - check that. */
402 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &dst_vb1
, 4);
403 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
405 memset(&vb_desc
, 0, sizeof(vb_desc
));
406 vb_desc
.dwSize
= sizeof(vb_desc
);
407 vb_desc
.dwFVF
= D3DFVF_XYZ
;
408 vb_desc
.dwNumVertices
= 5;
409 /* MSDN says that the last parameter must be 0 - check that. */
410 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &dst_vb2
, 12345678);
411 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
413 memset(&vp
, 0, sizeof(vp
));
420 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
421 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
423 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
424 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
425 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb2
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
426 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
428 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
429 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
430 ok(compare_vec4(&dst_data
[0], +1.280e+2f
, +1.280e+2f
, +0.000e+0f
, +1.000e+0f
, 4096),
431 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
432 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
433 ok(compare_vec4(&dst_data
[1], +1.920e+2f
, +6.400e+1f
, +1.000e+0f
, +1.000e+0f
, 4096),
434 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
435 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
436 ok(compare_vec4(&dst_data
[2], +6.400e+1f
, +1.920e+2f
, +5.000e-1f
, +1.000e+0f
, 4096),
437 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
438 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
439 ok(compare_vec4(&dst_data
[3], +1.600e+2f
, +1.600e+2f
, +2.500e-1f
, +1.000e+0f
, 4096),
440 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
441 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
442 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
443 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
445 hr
= IDirect3DVertexBuffer7_Lock(dst_vb2
, 0, (void **)&dst_data2
, NULL
);
446 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
447 /* Small thing without much practical meaning, but I stumbled upon it,
448 * so let's check for it: If the output vertex buffer has no RHW value,
449 * the RHW value of the last vertex is written into the next vertex. */
450 ok(compare_vec3(&dst_data2
[4], +1.000e+0f
, +0.000e+0f
, +0.000e+0f
, 4096),
451 "Got unexpected vertex 4 {%.8e, %.8e, %.8e}.\n",
452 dst_data2
[4].x
, dst_data2
[4].y
, dst_data2
[4].z
);
453 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb2
);
454 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
456 /* Try a more complicated viewport, same vertices. */
457 memset(&vp
, 0, sizeof(vp
));
464 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
465 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
467 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
468 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
470 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
471 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
472 ok(compare_vec4(&dst_data
[0], +1.330e+2f
, +7.000e+1f
, -2.000e+0f
, +1.000e+0f
, 4096),
473 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
474 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
475 ok(compare_vec4(&dst_data
[1], +2.560e+2f
, +5.000e+0f
, +4.000e+0f
, +1.000e+0f
, 4096),
476 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
477 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
478 ok(compare_vec4(&dst_data
[2], +1.000e+1f
, +1.350e+2f
, +1.000e+0f
, +1.000e+0f
, 4096),
479 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
480 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
481 ok(compare_vec4(&dst_data
[3], +1.945e+2f
, +1.025e+2f
, -5.000e-1f
, +1.000e+0f
, 4096),
482 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
483 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
484 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
485 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
487 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &world
);
488 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
489 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &view
);
490 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
491 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &proj
);
492 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
494 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
495 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
497 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
498 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
499 ok(compare_vec4(&dst_data
[0], +2.560e+2f
, +7.000e+1f
, -2.000e+0f
, +3.333e-1f
, 4096),
500 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
501 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
502 ok(compare_vec4(&dst_data
[1], +2.560e+2f
, +7.813e+1f
, -2.750e+0f
, +1.250e-1f
, 4096),
503 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
504 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
505 ok(compare_vec4(&dst_data
[2], +2.560e+2f
, +4.400e+1f
, +4.000e-1f
, +4.000e-1f
, 4096),
506 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
507 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
508 ok(compare_vec4(&dst_data
[3], +2.560e+2f
, +8.182e+1f
, -3.091e+0f
, +3.636e-1f
, 4096),
509 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
510 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
511 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
512 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
514 IDirect3DVertexBuffer7_Release(dst_vb2
);
515 IDirect3DVertexBuffer7_Release(dst_vb1
);
516 IDirect3DVertexBuffer7_Release(src_vb
);
517 IDirect3D7_Release(d3d7
);
518 IDirect3DDevice7_Release(device
);
519 DestroyWindow(window
);
522 static void test_coop_level_create_device_window(void)
524 HWND focus_window
, device_window
;
528 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
529 0, 0, 640, 480, 0, 0, 0, 0);
530 if (!(ddraw
= create_ddraw()))
532 skip("Failed to create a 3D device, skipping test.\n");
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
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
542 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
543 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
544 ok(!device_window
, "Unexpected device window found.\n");
545 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
546 ok(hr
== DDERR_INVALIDPARAMS
, "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_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
550 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
551 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
552 ok(!device_window
, "Unexpected device window found.\n");
553 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
554 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
555 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
556 ok(!device_window
, "Unexpected device window found.\n");
558 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
559 if (broken(hr
== DDERR_INVALIDPARAMS
))
561 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
562 IDirectDraw7_Release(ddraw
);
563 DestroyWindow(focus_window
);
567 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
568 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
569 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
570 ok(!device_window
, "Unexpected device window found.\n");
571 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
572 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
573 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
574 ok(!device_window
, "Unexpected device window found.\n");
576 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
577 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
578 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
579 ok(!device_window
, "Unexpected device window found.\n");
580 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
581 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
582 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
583 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
584 ok(!!device_window
, "Device window not found.\n");
586 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
587 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
588 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
589 ok(!device_window
, "Unexpected device window found.\n");
590 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
591 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
592 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
593 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
594 ok(!!device_window
, "Device window not found.\n");
596 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
597 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
598 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
599 ok(!device_window
, "Unexpected device window found.\n");
600 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
601 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
602 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
603 ok(!device_window
, "Unexpected device window found.\n");
604 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
605 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
606 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
607 ok(!device_window
, "Unexpected device window found.\n");
608 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
609 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
610 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
611 ok(!!device_window
, "Device window not found.\n");
613 IDirectDraw7_Release(ddraw
);
614 DestroyWindow(focus_window
);
617 static void test_clipper_blt(void)
619 IDirectDrawSurface7
*src_surface
, *dst_surface
;
620 RECT client_rect
, src_rect
, *rect
;
621 IDirectDrawClipper
*clipper
;
622 DDSURFACEDESC2 surface_desc
;
623 unsigned int i
, j
, x
, y
;
634 static const DWORD src_data
[] =
636 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
637 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
638 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
640 static const D3DCOLOR expected1
[] =
642 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
643 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
644 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
645 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
647 static const D3DCOLOR expected2
[] =
649 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
650 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
651 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
652 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
655 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
656 10, 10, 640, 480, 0, 0, 0, 0);
657 ShowWindow(window
, SW_SHOW
);
658 if (!(ddraw
= create_ddraw()))
660 skip("Failed to create a ddraw object, skipping test.\n");
661 DestroyWindow(window
);
665 ret
= GetClientRect(window
, &client_rect
);
666 ok(ret
, "Failed to get client rect.\n");
667 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
668 ok(ret
, "Failed to map client rect.\n");
670 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
671 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
673 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
674 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
675 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
676 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
677 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
678 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
679 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
680 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
681 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
682 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
683 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
684 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
685 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
686 ok(rgn_data
->rdh
.nCount
== 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
687 ok(rgn_data
->rdh
.nRgnSize
== 16, "Got unexpected region size %u.\n", rgn_data
->rdh
.nRgnSize
);
688 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
689 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
690 rgn_data
->rdh
.rcBound
.left
, rgn_data
->rdh
.rcBound
.top
,
691 rgn_data
->rdh
.rcBound
.right
, rgn_data
->rdh
.rcBound
.bottom
,
692 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
693 rect
= (RECT
*)&rgn_data
->Buffer
[0];
694 ok(EqualRect(rect
, &client_rect
),
695 "Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
696 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
697 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
698 HeapFree(GetProcessHeap(), 0, rgn_data
);
700 r1
= CreateRectRgn(0, 0, 320, 240);
701 ok(!!r1
, "Failed to create region.\n");
702 r2
= CreateRectRgn(320, 240, 640, 480);
703 ok(!!r2
, "Failed to create region.\n");
704 CombineRgn(r1
, r1
, r2
, RGN_OR
);
705 ret
= GetRegionData(r1
, 0, NULL
);
706 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
707 ret
= GetRegionData(r1
, ret
, rgn_data
);
708 ok(!!ret
, "Failed to get region data.\n");
713 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
714 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
715 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
716 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
717 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
718 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
720 HeapFree(GetProcessHeap(), 0, rgn_data
);
722 memset(&surface_desc
, 0, sizeof(surface_desc
));
723 surface_desc
.dwSize
= sizeof(surface_desc
);
724 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
725 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
726 surface_desc
.dwWidth
= 640;
727 surface_desc
.dwHeight
= 480;
728 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
729 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
730 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
731 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
732 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
733 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
735 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
736 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
737 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
738 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
740 memset(&fx
, 0, sizeof(fx
));
741 fx
.dwSize
= sizeof(fx
);
742 hr
= IDirectDrawSurface7_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
743 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
744 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
745 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
747 hr
= IDirectDrawSurface7_Lock(src_surface
, NULL
, &surface_desc
, 0, NULL
);
748 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
749 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
750 ptr
= surface_desc
.lpSurface
;
751 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
752 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
753 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
754 hr
= IDirectDrawSurface7_Unlock(src_surface
, NULL
);
755 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
757 hr
= IDirectDrawSurface7_SetClipper(dst_surface
, clipper
);
758 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
760 SetRect(&src_rect
, 1, 1, 5, 2);
761 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
762 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
763 for (i
= 0; i
< 4; ++i
)
765 for (j
= 0; j
< 4; ++j
)
767 x
= 80 * ((2 * j
) + 1);
768 y
= 60 * ((2 * i
) + 1);
769 color
= get_surface_color(dst_surface
, x
, y
);
770 ok(compare_color(color
, expected1
[i
* 4 + j
], 1),
771 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
775 U5(fx
).dwFillColor
= 0xff0000ff;
776 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
777 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
778 for (i
= 0; i
< 4; ++i
)
780 for (j
= 0; j
< 4; ++j
)
782 x
= 80 * ((2 * j
) + 1);
783 y
= 60 * ((2 * i
) + 1);
784 color
= get_surface_color(dst_surface
, x
, y
);
785 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
786 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
790 hr
= IDirectDrawSurface7_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
791 ok(hr
== DDERR_BLTFASTCANTCLIP
, "Got unexpected hr %#x.\n", hr
);
793 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
794 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
795 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
796 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
797 DestroyWindow(window
);
798 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
799 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
800 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
801 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
802 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
803 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
804 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
805 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
806 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
807 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
808 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
809 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
811 IDirectDrawSurface7_Release(dst_surface
);
812 IDirectDrawSurface7_Release(src_surface
);
813 IDirectDrawClipper_Release(clipper
);
814 IDirectDraw7_Release(ddraw
);
817 static void test_coop_level_d3d_state(void)
819 IDirectDrawSurface7
*rt
, *surface
;
820 IDirect3DDevice7
*device
;
828 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
829 0, 0, 640, 480, 0, 0, 0, 0);
830 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
832 skip("Failed to create D3D device, skipping test.\n");
833 DestroyWindow(window
);
837 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
838 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
839 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
840 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
841 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
842 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
843 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
844 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
845 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
846 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
847 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
848 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
849 color
= get_surface_color(rt
, 320, 240);
850 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
852 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
853 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
854 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
855 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
856 IDirect3D7_Release(d3d
);
857 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
858 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
859 hr
= IDirectDrawSurface7_IsLost(rt
);
860 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
861 hr
= IDirectDraw7_RestoreAllSurfaces(ddraw
);
862 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
863 IDirectDraw7_Release(ddraw
);
865 hr
= IDirect3DDevice7_GetRenderTarget(device
, &surface
);
866 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
867 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
868 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
869 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
870 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
871 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
872 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
873 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
874 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
875 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
876 color
= get_surface_color(rt
, 320, 240);
877 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
879 IDirectDrawSurface7_Release(surface
);
880 IDirectDrawSurface7_Release(rt
);
881 IDirect3DDevice7_Release(device
);
882 DestroyWindow(window
);
885 static void test_surface_interface_mismatch(void)
887 IDirectDraw7
*ddraw
= NULL
;
888 IDirect3D7
*d3d
= NULL
;
889 IDirectDrawSurface7
*surface
= NULL
, *ds
;
890 IDirectDrawSurface3
*surface3
= NULL
;
891 IDirect3DDevice7
*device
= NULL
;
892 DDSURFACEDESC2 surface_desc
;
899 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
900 0, 0, 640, 480, 0, 0, 0, 0);
902 if (!(ddraw
= create_ddraw()))
904 skip("Failed to create a ddraw object, skipping test.\n");
908 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
909 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
911 memset(&surface_desc
, 0, sizeof(surface_desc
));
912 surface_desc
.dwSize
= sizeof(surface_desc
);
913 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
914 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
915 surface_desc
.dwWidth
= 640;
916 surface_desc
.dwHeight
= 480;
918 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
919 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
921 hr
= IDirectDrawSurface7_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
922 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface3, hr %#x.\n", hr
);
924 hr
= IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d
);
927 skip("Failed to get the IDirect3D7 interface, skipping test.\n");
931 memset(&z_fmt
, 0, sizeof(z_fmt
));
932 hr
= IDirect3D7_EnumZBufferFormats(d3d
, &IID_IDirect3DTnLHalDevice
, enum_z_fmt
, &z_fmt
);
933 if (FAILED(hr
) || !z_fmt
.dwSize
)
935 skip("No depth buffer formats available, skipping test.\n");
939 memset(&surface_desc
, 0, sizeof(surface_desc
));
940 surface_desc
.dwSize
= sizeof(surface_desc
);
941 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
942 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
943 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
944 surface_desc
.dwWidth
= 640;
945 surface_desc
.dwHeight
= 480;
946 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
947 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
951 /* Using a different surface interface version still works */
952 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
953 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
954 refcount
= IDirectDrawSurface7_Release(ds
);
955 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
960 hr
= IDirect3D7_CreateDevice(d3d
, &IID_IDirect3DTnLHalDevice
, (IDirectDrawSurface7
*)surface3
, &device
);
961 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
965 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
966 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
967 color
= get_surface_color(surface
, 320, 240);
968 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
971 if (surface3
) IDirectDrawSurface3_Release(surface3
);
972 if (surface
) IDirectDrawSurface7_Release(surface
);
973 if (device
) IDirect3DDevice7_Release(device
);
974 if (d3d
) IDirect3D7_Release(d3d
);
975 if (ddraw
) IDirectDraw7_Release(ddraw
);
976 DestroyWindow(window
);
979 static void test_coop_level_threaded(void)
981 struct create_window_thread_param p
;
985 if (!(ddraw
= create_ddraw()))
987 skip("Failed to create a ddraw object, skipping test.\n");
990 create_window_thread(&p
);
992 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
993 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
995 IDirectDraw7_Release(ddraw
);
996 destroy_window_thread(&p
);
999 static void test_depth_blit(void)
1001 IDirect3DDevice7
*device
;
1009 { -1.0, 1.0, 0.50f
, 0xff00ff00},
1010 { 1.0, 1.0, 0.50f
, 0xff00ff00},
1011 { -1.0, -1.0, 0.50f
, 0xff00ff00},
1012 { 1.0, -1.0, 0.50f
, 0xff00ff00},
1014 static const D3DCOLOR expected_colors
[4][4] =
1016 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1017 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1018 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1019 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1021 DDSURFACEDESC2 ddsd_new
, ddsd_existing
;
1023 IDirectDrawSurface7
*ds1
, *ds2
, *ds3
, *rt
;
1024 RECT src_rect
, dst_rect
;
1029 IDirectDraw7
*ddraw
;
1033 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1034 0, 0, 640, 480, 0, 0, 0, 0);
1035 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1037 skip("Failed to create D3D device, skipping test.\n");
1038 DestroyWindow(window
);
1042 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1043 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
1044 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1045 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
1046 IDirect3D7_Release(d3d
);
1048 ds1
= get_depth_stencil(device
);
1050 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1051 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1052 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1053 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1054 hr
= IDirectDrawSurface7_GetSurfaceDesc(ds1
, &ddsd_existing
);
1055 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1056 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1057 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1058 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1059 U4(ddsd_new
).ddpfPixelFormat
= U4(ddsd_existing
).ddpfPixelFormat
;
1060 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1061 ok(SUCCEEDED(hr
), "Failed to create a z buffer, hr %#x.\n", hr
);
1062 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1063 ok(SUCCEEDED(hr
), "Failed to create a z buffer, hr %#x.\n", hr
);
1064 IDirectDraw7_Release(ddraw
);
1066 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1067 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
1068 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1069 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
1070 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
1071 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
1073 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
1074 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
1077 SetRect(&src_rect
, 0, 0, 320, 240);
1078 SetRect(&dst_rect
, 0, 0, 320, 240);
1079 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1080 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1081 /* Different locations. */
1082 SetRect(&src_rect
, 0, 0, 320, 240);
1083 SetRect(&dst_rect
, 320, 240, 640, 480);
1084 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1085 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1087 SetRect(&src_rect
, 0, 0, 320, 240);
1088 SetRect(&dst_rect
, 0, 0, 640, 480);
1089 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1090 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1092 SetRect(&src_rect
, 0, 480, 640, 0);
1093 SetRect(&dst_rect
, 0, 0, 640, 480);
1094 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1095 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1096 SetRect(&src_rect
, 0, 0, 640, 480);
1097 SetRect(&dst_rect
, 0, 480, 640, 0);
1098 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1099 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1100 /* Full, explicit. */
1101 SetRect(&src_rect
, 0, 0, 640, 480);
1102 SetRect(&dst_rect
, 0, 0, 640, 480);
1103 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1104 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1105 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1107 /* Depth blit inside a BeginScene / EndScene pair */
1108 hr
= IDirect3DDevice7_BeginScene(device
);
1109 ok(SUCCEEDED(hr
), "Failed to start scene, hr %#x.\n", hr
);
1110 /* From the current depth stencil */
1111 hr
= IDirectDrawSurface7_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1112 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1113 /* To the current depth stencil */
1114 hr
= IDirectDrawSurface7_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1115 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1116 /* Between unbound surfaces */
1117 hr
= IDirectDrawSurface7_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1118 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1119 hr
= IDirect3DDevice7_EndScene(device
);
1120 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1122 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1123 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1124 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1125 * a reliable result(z = 0.0) */
1126 memset(&fx
, 0, sizeof(fx
));
1127 fx
.dwSize
= sizeof(fx
);
1128 hr
= IDirectDrawSurface7_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1129 ok(SUCCEEDED(hr
), "Failed to clear the source z buffer, hr %#x.\n", hr
);
1131 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
1132 ok(SUCCEEDED(hr
), "Failed to clear the color and z buffers, hr %#x.\n", hr
);
1133 SetRect(&dst_rect
, 0, 0, 320, 240);
1134 hr
= IDirectDrawSurface7_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1135 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1136 IDirectDrawSurface7_Release(ds3
);
1137 IDirectDrawSurface7_Release(ds2
);
1138 IDirectDrawSurface7_Release(ds1
);
1140 hr
= IDirect3DDevice7_BeginScene(device
);
1141 ok(SUCCEEDED(hr
), "Failed to start scene, hr %#x.\n", hr
);
1142 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
1144 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1145 hr
= IDirect3DDevice7_EndScene(device
);
1146 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1148 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1149 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1150 for (i
= 0; i
< 4; ++i
)
1152 for (j
= 0; j
< 4; ++j
)
1154 unsigned int x
= 80 * ((2 * j
) + 1);
1155 unsigned int y
= 60 * ((2 * i
) + 1);
1156 color
= get_surface_color(rt
, x
, y
);
1157 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1158 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1162 IDirectDrawSurface7_Release(rt
);
1163 IDirect3DDevice7_Release(device
);
1164 DestroyWindow(window
);
1167 static void test_texture_load_ckey(void)
1170 IDirect3DDevice7
*device
;
1171 IDirectDraw7
*ddraw
;
1172 IDirectDrawSurface7
*src
;
1173 IDirectDrawSurface7
*dst
;
1174 DDSURFACEDESC2 ddsd
;
1179 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1180 0, 0, 640, 480, 0, 0, 0, 0);
1181 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1183 skip("Failed to create D3D device, skipping test.\n");
1184 DestroyWindow(window
);
1188 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1189 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
1190 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1191 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
1192 IDirect3D7_Release(d3d
);
1194 memset(&ddsd
, 0, sizeof(ddsd
));
1195 ddsd
.dwSize
= sizeof(ddsd
);
1196 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1197 ddsd
.dwHeight
= 128;
1199 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1200 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1201 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1202 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1203 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1204 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1206 /* No surface has a color key */
1207 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1208 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1209 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1210 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1211 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1212 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1213 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1215 /* Source surface has a color key */
1216 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1217 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1218 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1219 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1220 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1221 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1222 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1223 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1224 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1226 /* Both surfaces have a color key: Dest ckey is overwritten */
1227 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1228 hr
= IDirectDrawSurface7_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1229 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1230 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1231 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1232 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1233 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1234 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1235 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1237 /* Only the destination has a color key: It is deleted. This behavior differs from
1238 * IDirect3DTexture(2)::Load */
1239 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1240 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1241 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1242 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1243 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1244 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1245 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1246 todo_wine
ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1248 IDirectDrawSurface7_Release(dst
);
1249 IDirectDrawSurface7_Release(src
);
1250 IDirectDraw7_Release(ddraw
);
1251 IDirect3DDevice7_Release(device
);
1254 static void test_zenable(void)
1258 struct vec4 position
;
1263 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1264 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1265 {{640.0f
, 480.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1266 {{640.0f
, 0.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1268 IDirect3DDevice7
*device
;
1269 IDirectDrawSurface7
*rt
;
1276 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1277 0, 0, 640, 480, 0, 0, 0, 0);
1278 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1280 skip("Failed to create D3D device, skipping test.\n");
1281 DestroyWindow(window
);
1285 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1286 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
1288 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
1289 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1290 hr
= IDirect3DDevice7_BeginScene(device
);
1291 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1292 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
, tquad
, 4, 0);
1293 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1294 hr
= IDirect3DDevice7_EndScene(device
);
1295 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1297 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1298 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1299 for (i
= 0; i
< 4; ++i
)
1301 for (j
= 0; j
< 4; ++j
)
1303 x
= 80 * ((2 * j
) + 1);
1304 y
= 60 * ((2 * i
) + 1);
1305 color
= get_surface_color(rt
, x
, y
);
1306 ok(compare_color(color
, 0x0000ff00, 1),
1307 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1310 IDirectDrawSurface7_Release(rt
);
1312 IDirect3DDevice7_Release(device
);
1313 DestroyWindow(window
);
1316 static void test_ck_rgba(void)
1320 struct vec4 position
;
1321 struct vec2 texcoord
;
1325 {{ 0.0f
, 480.0f
, 0.25f
, 1.0f
}, {0.0f
, 0.0f
}},
1326 {{ 0.0f
, 0.0f
, 0.25f
, 1.0f
}, {0.0f
, 1.0f
}},
1327 {{640.0f
, 480.0f
, 0.25f
, 1.0f
}, {1.0f
, 0.0f
}},
1328 {{640.0f
, 0.0f
, 0.25f
, 1.0f
}, {1.0f
, 1.0f
}},
1329 {{ 0.0f
, 480.0f
, 0.75f
, 1.0f
}, {0.0f
, 0.0f
}},
1330 {{ 0.0f
, 0.0f
, 0.75f
, 1.0f
}, {0.0f
, 1.0f
}},
1331 {{640.0f
, 480.0f
, 0.75f
, 1.0f
}, {1.0f
, 0.0f
}},
1332 {{640.0f
, 0.0f
, 0.75f
, 1.0f
}, {1.0f
, 1.0f
}},
1336 D3DCOLOR fill_color
;
1344 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x000000ff},
1345 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x000000ff},
1346 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00},
1347 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1348 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00807f00},
1349 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x0000ff00},
1350 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00},
1351 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1354 IDirectDrawSurface7
*texture
;
1355 DDSURFACEDESC2 surface_desc
;
1356 IDirect3DDevice7
*device
;
1357 IDirectDrawSurface7
*rt
;
1358 IDirectDraw7
*ddraw
;
1366 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1367 0, 0, 640, 480, 0, 0, 0, 0);
1368 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1370 skip("Failed to create D3D device, skipping test.\n");
1371 DestroyWindow(window
);
1375 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1376 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1377 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1378 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1379 IDirect3D7_Release(d3d
);
1381 memset(&surface_desc
, 0, sizeof(surface_desc
));
1382 surface_desc
.dwSize
= sizeof(surface_desc
);
1383 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1384 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1385 surface_desc
.dwWidth
= 256;
1386 surface_desc
.dwHeight
= 256;
1387 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1388 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1389 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1390 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1391 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1392 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1393 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1394 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1395 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1396 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
1397 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1399 hr
= IDirect3DDevice7_SetTexture(device
, 0, texture
);
1400 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1401 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1402 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1403 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1404 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1406 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1407 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1409 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
1411 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1412 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1413 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1414 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1416 memset(&fx
, 0, sizeof(fx
));
1417 fx
.dwSize
= sizeof(fx
);
1418 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1419 hr
= IDirectDrawSurface7_Blt(texture
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1420 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1422 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
1423 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1424 hr
= IDirect3DDevice7_BeginScene(device
);
1425 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1426 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1427 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1428 hr
= IDirect3DDevice7_EndScene(device
);
1429 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1431 color
= get_surface_color(rt
, 320, 240);
1433 todo_wine
ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1434 tests
[i
].result1
, i
, color
);
1436 ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1437 tests
[i
].result1
, i
, color
);
1439 U5(fx
).dwFillColor
= 0xff0000ff;
1440 hr
= IDirectDrawSurface7_Blt(texture
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1441 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1443 hr
= IDirect3DDevice7_BeginScene(device
);
1444 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1445 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[4], 4, 0);
1446 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1447 hr
= IDirect3DDevice7_EndScene(device
);
1448 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1450 /* This tests that fragments that are masked out by the color key are
1451 * discarded, instead of just fully transparent. */
1452 color
= get_surface_color(rt
, 320, 240);
1454 todo_wine
ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1455 tests
[i
].result2
, i
, color
);
1457 ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1458 tests
[i
].result2
, i
, color
);
1461 IDirectDrawSurface7_Release(rt
);
1462 IDirectDrawSurface7_Release(texture
);
1463 IDirectDraw7_Release(ddraw
);
1464 IDirect3DDevice7_Release(device
);
1465 DestroyWindow(window
);
1468 static void test_ck_default(void)
1472 struct vec4 position
;
1473 struct vec2 texcoord
;
1477 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
}},
1478 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, {0.0f
, 1.0f
}},
1479 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
1480 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, {1.0f
, 1.0f
}},
1482 IDirectDrawSurface7
*surface
, *rt
;
1483 DDSURFACEDESC2 surface_desc
;
1484 IDirect3DDevice7
*device
;
1485 IDirectDraw7
*ddraw
;
1493 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1494 0, 0, 640, 480, 0, 0, 0, 0);
1496 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1498 skip("Failed to create D3D device, skipping test.\n");
1499 DestroyWindow(window
);
1503 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1504 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1505 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1506 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1507 IDirect3D7_Release(d3d
);
1509 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1510 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1512 memset(&surface_desc
, 0, sizeof(surface_desc
));
1513 surface_desc
.dwSize
= sizeof(surface_desc
);
1514 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1515 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1516 surface_desc
.dwWidth
= 256;
1517 surface_desc
.dwHeight
= 256;
1518 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1519 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1520 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1521 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1522 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1523 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1524 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
1525 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
1526 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1527 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1528 hr
= IDirect3DDevice7_SetTexture(device
, 0, surface
);
1529 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1531 memset(&fx
, 0, sizeof(fx
));
1532 fx
.dwSize
= sizeof(fx
);
1533 U5(fx
).dwFillColor
= 0x000000ff;
1534 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1535 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
1537 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
1538 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1539 hr
= IDirect3DDevice7_BeginScene(device
);
1540 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1541 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1542 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1543 ok(!value
, "Got unexpected color keying state %#x.\n", value
);
1544 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1545 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1546 hr
= IDirect3DDevice7_EndScene(device
);
1547 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1548 color
= get_surface_color(rt
, 320, 240);
1549 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1551 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
1552 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1553 hr
= IDirect3DDevice7_BeginScene(device
);
1554 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1555 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
1556 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1557 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1558 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1559 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1560 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1561 ok(!!value
, "Got unexpected color keying state %#x.\n", value
);
1562 hr
= IDirect3DDevice7_EndScene(device
);
1563 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1564 color
= get_surface_color(rt
, 320, 240);
1565 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1567 IDirectDrawSurface7_Release(surface
);
1568 IDirectDrawSurface7_Release(rt
);
1569 IDirect3DDevice7_Release(device
);
1570 IDirectDraw7_Release(ddraw
);
1571 DestroyWindow(window
);
1577 REFIID refcount_iid
;
1581 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
1582 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
1584 ULONG refcount
, expected_refcount
;
1585 IUnknown
*iface1
, *iface2
;
1589 for (i
= 0; i
< entry_count
; ++i
)
1591 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
1592 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
1595 for (j
= 0; j
< entry_count
; ++j
)
1597 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
1598 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
1601 expected_refcount
= 0;
1602 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
1603 ++expected_refcount
;
1604 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
1605 ++expected_refcount
;
1606 refcount
= IUnknown_Release(iface2
);
1607 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
1608 refcount
, test_name
, i
, j
, expected_refcount
);
1612 expected_refcount
= 0;
1613 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
1614 ++expected_refcount
;
1615 refcount
= IUnknown_Release(iface1
);
1616 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
1617 refcount
, test_name
, i
, expected_refcount
);
1622 static void test_surface_qi(void)
1624 static const struct qi_test tests
[] =
1626 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
1627 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
1628 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
1629 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1630 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
1631 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
1632 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
1633 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
1634 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
1635 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
1636 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
1637 {&IID_IDirect3DDevice2
, NULL
, E_NOINTERFACE
},
1638 {&IID_IDirect3DDevice
, NULL
, E_NOINTERFACE
},
1639 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
1640 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
1641 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
1642 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
1643 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
1644 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
1645 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
1646 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
1647 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
1648 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
1649 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
1650 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
1651 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
1652 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
1653 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
1654 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
1655 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
1656 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
1657 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
1658 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
1659 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
1660 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
1661 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
1662 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
1663 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
1664 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
1665 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
1666 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
1667 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
1670 IDirectDrawSurface7
*surface
;
1671 DDSURFACEDESC2 surface_desc
;
1672 IDirect3DDevice7
*device
;
1673 IDirectDraw7
*ddraw
;
1677 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1678 0, 0, 640, 480, 0, 0, 0, 0);
1679 /* Try to create a D3D device to see if the ddraw implementation supports
1680 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
1681 * doesn't support e.g. the IDirect3DTexture interfaces. */
1682 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1684 skip("Failed to create D3D device, skipping test.\n");
1685 DestroyWindow(window
);
1688 IDirect3DDevice_Release(device
);
1689 if (!(ddraw
= create_ddraw()))
1691 skip("Failed to create a ddraw object, skipping test.\n");
1692 DestroyWindow(window
);
1695 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1696 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1698 memset(&surface_desc
, 0, sizeof(surface_desc
));
1699 surface_desc
.dwSize
= sizeof(surface_desc
);
1700 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1701 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1702 surface_desc
.dwWidth
= 512;
1703 surface_desc
.dwHeight
= 512;
1704 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1705 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1707 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface7
, tests
, sizeof(tests
) / sizeof(*tests
));
1709 IDirectDrawSurface7_Release(surface
);
1710 IDirectDraw7_Release(ddraw
);
1711 DestroyWindow(window
);
1714 static void test_device_qi(void)
1716 static const struct qi_test tests
[] =
1718 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
1719 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
1720 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
1721 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1722 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
1723 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
1724 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
1725 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
1726 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
1727 {&IID_IDirect3DDevice7
, &IID_IDirect3DDevice7
, S_OK
},
1728 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
1729 {&IID_IDirect3DDevice2
, NULL
, E_NOINTERFACE
},
1730 {&IID_IDirect3DDevice
, NULL
, E_NOINTERFACE
},
1731 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
1732 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
1733 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
1734 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
1735 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
1736 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
1737 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
1738 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
1739 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
1740 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
1741 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
1742 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
1743 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
1744 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
1745 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
1746 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
1747 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
1748 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
1749 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
1750 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
1751 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
1752 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
1753 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
1754 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
1755 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
1756 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
1757 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
1758 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
1759 {&IID_IUnknown
, &IID_IDirect3DDevice7
, S_OK
},
1762 IDirect3DDevice7
*device
;
1765 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1766 0, 0, 640, 480, 0, 0, 0, 0);
1767 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1769 skip("Failed to create D3D device, skipping test.\n");
1770 DestroyWindow(window
);
1774 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice7
, tests
, sizeof(tests
) / sizeof(*tests
));
1776 IDirect3DDevice7_Release(device
);
1777 DestroyWindow(window
);
1780 static void test_wndproc(void)
1782 LONG_PTR proc
, ddraw_proc
;
1783 IDirectDraw7
*ddraw
;
1789 static const UINT messages
[] =
1791 WM_WINDOWPOSCHANGING
,
1794 WM_WINDOWPOSCHANGING
,
1800 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
1801 if (!(ddraw
= create_ddraw()))
1803 skip("Failed to create IDirectDraw7 object, skipping tests.\n");
1807 wc
.lpfnWndProc
= test_proc
;
1808 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
1809 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
1811 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
1812 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
1814 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1815 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1816 (LONG_PTR
)test_proc
, proc
);
1817 expect_messages
= messages
;
1818 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1819 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1820 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
1821 expect_messages
= NULL
;
1822 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1823 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1824 (LONG_PTR
)test_proc
, proc
);
1825 ref
= IDirectDraw7_Release(ddraw
);
1826 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1827 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1828 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1829 (LONG_PTR
)test_proc
, proc
);
1831 /* DDSCL_NORMAL doesn't. */
1832 ddraw
= create_ddraw();
1833 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1834 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1835 (LONG_PTR
)test_proc
, proc
);
1836 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
1837 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1838 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1839 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1840 (LONG_PTR
)test_proc
, proc
);
1841 ref
= IDirectDraw7_Release(ddraw
);
1842 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1843 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1844 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1845 (LONG_PTR
)test_proc
, proc
);
1847 /* The original window proc is only restored by ddraw if the current
1848 * window proc matches the one ddraw set. This also affects switching
1849 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
1850 ddraw
= create_ddraw();
1851 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1852 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1853 (LONG_PTR
)test_proc
, proc
);
1854 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1855 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1856 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1857 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1858 (LONG_PTR
)test_proc
, proc
);
1860 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1861 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1862 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1863 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1864 (LONG_PTR
)test_proc
, proc
);
1865 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1866 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1867 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
1868 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1869 (LONG_PTR
)test_proc
, proc
);
1870 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1871 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1872 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1873 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
1874 (LONG_PTR
)DefWindowProcA
, proc
);
1875 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1876 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1877 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)ddraw_proc
);
1878 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
1879 (LONG_PTR
)DefWindowProcA
, proc
);
1880 ref
= IDirectDraw7_Release(ddraw
);
1881 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1882 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1883 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1884 (LONG_PTR
)test_proc
, proc
);
1886 ddraw
= create_ddraw();
1887 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1888 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1889 (LONG_PTR
)test_proc
, proc
);
1890 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1891 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1892 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
1893 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1894 (LONG_PTR
)test_proc
, proc
);
1895 ref
= IDirectDraw7_Release(ddraw
);
1896 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1897 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1898 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
1899 (LONG_PTR
)DefWindowProcA
, proc
);
1901 fix_wndproc(window
, (LONG_PTR
)test_proc
);
1902 expect_messages
= NULL
;
1903 DestroyWindow(window
);
1904 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
1907 static void test_window_style(void)
1909 LONG style
, exstyle
, tmp
;
1910 RECT fullscreen_rect
, r
;
1911 IDirectDraw7
*ddraw
;
1916 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1917 0, 0, 100, 100, 0, 0, 0, 0);
1918 if (!(ddraw
= create_ddraw()))
1920 skip("Failed to create a ddraw object, skipping test.\n");
1921 DestroyWindow(window
);
1925 style
= GetWindowLongA(window
, GWL_STYLE
);
1926 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
1927 SetRect(&fullscreen_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
1929 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1930 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1932 tmp
= GetWindowLongA(window
, GWL_STYLE
);
1933 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
1934 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
1935 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
1937 GetWindowRect(window
, &r
);
1938 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
1939 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
1940 r
.left
, r
.top
, r
.right
, r
.bottom
);
1941 GetClientRect(window
, &r
);
1942 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
1944 ref
= IDirectDraw7_Release(ddraw
);
1945 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1947 DestroyWindow(window
);
1952 HMODULE module
= GetModuleHandleA("ddraw.dll");
1954 if (!(pDirectDrawCreateEx
= (void *)GetProcAddress(module
, "DirectDrawCreateEx")))
1956 win_skip("DirectDrawCreateEx not available, skipping tests.\n");
1960 test_process_vertices();
1961 test_coop_level_create_device_window();
1963 test_coop_level_d3d_state();
1964 test_surface_interface_mismatch();
1965 test_coop_level_threaded();
1967 test_texture_load_ckey();
1974 test_window_style();