2 * Copyright 2011 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "wine/test.h"
39 struct create_window_thread_param
42 HANDLE window_created
;
43 HANDLE destroy_window
;
47 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
57 if (abs(x
- y
) > ulps
)
63 static BOOL
compare_vec4(struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
65 return compare_float(vec
->x
, x
, ulps
)
66 && compare_float(vec
->y
, y
, ulps
)
67 && compare_float(vec
->z
, z
, ulps
)
68 && compare_float(vec
->w
, w
, ulps
);
71 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
73 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
75 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
77 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
79 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
83 static DWORD WINAPI
create_window_thread_proc(void *param
)
85 struct create_window_thread_param
*p
= param
;
89 p
->window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
90 0, 0, 640, 480, 0, 0, 0, 0);
91 ret
= SetEvent(p
->window_created
);
92 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
98 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
))
99 DispatchMessage(&msg
);
100 res
= WaitForSingleObject(p
->destroy_window
, 100);
101 if (res
== WAIT_OBJECT_0
)
103 if (res
!= WAIT_TIMEOUT
)
105 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
110 DestroyWindow(p
->window
);
115 static void create_window_thread(struct create_window_thread_param
*p
)
119 p
->window_created
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
120 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
121 p
->destroy_window
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
122 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
123 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
124 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
125 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
126 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
129 static void destroy_window_thread(struct create_window_thread_param
*p
)
131 SetEvent(p
->destroy_window
);
132 WaitForSingleObject(p
->thread
, INFINITE
);
133 CloseHandle(p
->destroy_window
);
134 CloseHandle(p
->window_created
);
135 CloseHandle(p
->thread
);
138 static IDirectDrawSurface4
*get_depth_stencil(IDirect3DDevice3
*device
)
140 IDirectDrawSurface4
*rt
, *ret
;
141 DDSCAPS2 caps
= {DDSCAPS_ZBUFFER
, 0, 0, 0};
144 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
145 ok(SUCCEEDED(hr
), "Failed to get the render target, hr %#x.\n", hr
);
146 hr
= IDirectDrawSurface4_GetAttachedSurface(rt
, &caps
, &ret
);
147 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
148 IDirectDrawSurface4_Release(rt
);
152 static D3DCOLOR
get_surface_color(IDirectDrawSurface4
*surface
, UINT x
, UINT y
)
154 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
155 DDSURFACEDESC2 surface_desc
;
159 memset(&surface_desc
, 0, sizeof(surface_desc
));
160 surface_desc
.dwSize
= sizeof(surface_desc
);
162 hr
= IDirectDrawSurface4_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
163 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
167 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
169 hr
= IDirectDrawSurface4_Unlock(surface
, &rect
);
170 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
175 static HRESULT CALLBACK
enum_z_fmt(DDPIXELFORMAT
*format
, void *ctx
)
177 DDPIXELFORMAT
*z_fmt
= ctx
;
179 if (U1(*format
).dwZBufferBitDepth
> U1(*z_fmt
).dwZBufferBitDepth
)
185 static IDirectDraw4
*create_ddraw(void)
187 IDirectDraw4
*ddraw4
;
191 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
194 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw4
, (void **)&ddraw4
);
195 IDirectDraw_Release(ddraw1
);
202 static IDirect3DDevice3
*create_device(HWND window
, DWORD coop_level
)
204 IDirectDrawSurface4
*surface
, *ds
;
205 IDirect3DDevice3
*device
= NULL
;
206 DDSURFACEDESC2 surface_desc
;
207 IDirectDraw4
*ddraw4
;
212 if (!(ddraw4
= create_ddraw()))
215 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, coop_level
);
216 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
218 memset(&surface_desc
, 0, sizeof(surface_desc
));
219 surface_desc
.dwSize
= sizeof(surface_desc
);
220 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
221 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
222 surface_desc
.dwWidth
= 640;
223 surface_desc
.dwHeight
= 480;
225 hr
= IDirectDraw4_CreateSurface(ddraw4
, &surface_desc
, &surface
, NULL
);
226 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
228 if (coop_level
& DDSCL_NORMAL
)
230 IDirectDrawClipper
*clipper
;
232 hr
= IDirectDraw4_CreateClipper(ddraw4
, 0, &clipper
, NULL
);
233 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
234 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
235 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
236 hr
= IDirectDrawSurface4_SetClipper(surface
, clipper
);
237 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
238 IDirectDrawClipper_Release(clipper
);
241 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirect3D3
, (void **)&d3d3
);
242 IDirectDraw4_Release(ddraw4
);
245 IDirectDrawSurface4_Release(surface
);
249 memset(&z_fmt
, 0, sizeof(z_fmt
));
250 hr
= IDirect3D3_EnumZBufferFormats(d3d3
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
251 if (FAILED(hr
) || !z_fmt
.dwSize
)
253 IDirect3D3_Release(d3d3
);
254 IDirectDrawSurface4_Release(surface
);
258 memset(&surface_desc
, 0, sizeof(surface_desc
));
259 surface_desc
.dwSize
= sizeof(surface_desc
);
260 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
261 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
262 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
263 surface_desc
.dwWidth
= 640;
264 surface_desc
.dwHeight
= 480;
265 hr
= IDirectDraw4_CreateSurface(ddraw4
, &surface_desc
, &ds
, NULL
);
266 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
269 IDirect3D3_Release(d3d3
);
270 IDirectDrawSurface4_Release(surface
);
274 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
275 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
276 IDirectDrawSurface4_Release(ds
);
279 IDirect3D3_Release(d3d3
);
280 IDirectDrawSurface4_Release(surface
);
284 hr
= IDirect3D3_CreateDevice(d3d3
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
285 IDirect3D3_Release(d3d3
);
286 IDirectDrawSurface4_Release(surface
);
293 static void test_process_vertices(void)
295 IDirect3DVertexBuffer
*src_vb
, *dst_vb
;
296 IDirect3DViewport3
*viewport
;
297 D3DVERTEXBUFFERDESC vb_desc
;
298 IDirect3DDevice3
*device
;
299 struct vec3
*src_data
;
300 struct vec4
*dst_data
;
307 static D3DMATRIX identity
=
309 1.0f
, 0.0f
, 0.0f
, 0.0f
,
310 0.0f
, 1.0f
, 0.0f
, 0.0f
,
311 0.0f
, 0.0f
, 1.0f
, 0.0f
,
312 0.0f
, 0.0f
, 0.0f
, 1.0f
,
314 static D3DMATRIX projection
=
316 1.0f
, 0.0f
, 0.0f
, 0.0f
,
317 0.0f
, 1.0f
, 0.0f
, 0.0f
,
318 0.0f
, 0.0f
, 1.0f
, 0.0f
,
319 6.0f
, 7.0f
, 8.0f
, 1.0f
,
322 window
= CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW
,
323 0, 0, 640, 480, 0, 0, 0, 0);
324 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
326 skip("Failed to create a 3D device, skipping test.\n");
327 DestroyWindow(window
);
331 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d3
);
332 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
334 memset(&vb_desc
, 0, sizeof(vb_desc
));
335 vb_desc
.dwSize
= sizeof(vb_desc
);
336 vb_desc
.dwFVF
= D3DFVF_XYZ
;
337 vb_desc
.dwNumVertices
= 3;
338 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &src_vb
, 0, NULL
);
339 ok(SUCCEEDED(hr
), "Failed to create source vertex buffer, hr %#x.\n", hr
);
341 hr
= IDirect3DVertexBuffer_Lock(src_vb
, DDLOCK_WRITEONLY
, (void **)&src_data
, NULL
);
342 ok(SUCCEEDED(hr
), "Failed to lock source vertex buffer, hr %#x.\n", hr
);
343 src_data
[0].x
= -1.0f
;
344 src_data
[0].y
= -1.0f
;
345 src_data
[0].z
= -1.0f
;
346 src_data
[1].x
= 0.0f
;
347 src_data
[1].y
= 0.0f
;
348 src_data
[1].z
= 0.0f
;
349 src_data
[2].x
= 1.0f
;
350 src_data
[2].y
= 1.0f
;
351 src_data
[2].z
= 1.0f
;
352 hr
= IDirect3DVertexBuffer_Unlock(src_vb
);
353 ok(SUCCEEDED(hr
), "Failed to unlock source vertex buffer, hr %#x.\n", hr
);
355 memset(&vb_desc
, 0, sizeof(vb_desc
));
356 vb_desc
.dwSize
= sizeof(vb_desc
);
357 vb_desc
.dwFVF
= D3DFVF_XYZRHW
;
358 vb_desc
.dwNumVertices
= 3;
359 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &dst_vb
, 0, NULL
);
360 ok(SUCCEEDED(hr
), "Failed to create destination vertex buffer, hr %#x.\n", hr
);
362 hr
= IDirect3D3_CreateViewport(d3d3
, &viewport
, NULL
);
363 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
364 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
365 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
366 vp2
.dwSize
= sizeof(vp2
);
373 vp2
.dvClipWidth
= 4.0f
;
374 vp2
.dvClipHeight
= 5.0f
;
377 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
378 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
379 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
380 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
382 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &identity
);
383 ok(SUCCEEDED(hr
), "Failed to set world transformation, hr %#x.\n", hr
);
384 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &identity
);
385 ok(SUCCEEDED(hr
), "Failed to set view transformation, hr %#x.\n", hr
);
386 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &identity
);
387 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
389 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
390 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
392 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
393 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
394 ok(compare_vec4(&dst_data
[0], -6.500e+1f
, +1.800e+2f
, +2.000e-1f
, +1.000e+0f
, 4096),
395 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
396 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
397 ok(compare_vec4(&dst_data
[1], -4.000e+1f
, +1.400e+2f
, +4.000e-1f
, +1.000e+0f
, 4096),
398 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
399 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
400 ok(compare_vec4(&dst_data
[2], -1.500e+1f
, +1.000e+2f
, +6.000e-1f
, +1.000e+0f
, 4096),
401 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
402 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
403 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
404 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
406 hr
= IDirect3DDevice3_MultiplyTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &projection
);
407 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
409 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
410 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
412 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
413 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
414 ok(compare_vec4(&dst_data
[0], +8.500e+1f
, -1.000e+2f
, +1.800e+0f
, +1.000e+0f
, 4096),
415 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
416 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
417 ok(compare_vec4(&dst_data
[1], +1.100e+2f
, -1.400e+2f
, +2.000e+0f
, +1.000e+0f
, 4096),
418 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
419 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
420 ok(compare_vec4(&dst_data
[2], +1.350e+2f
, -1.800e+2f
, +2.200e+0f
, +1.000e+0f
, 4096),
421 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
422 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
423 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
424 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
426 vp2
.dwSize
= sizeof(vp2
);
433 vp2
.dvClipWidth
= 2.0f
;
434 vp2
.dvClipHeight
= 4.0f
;
437 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
438 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
440 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
441 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
443 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
444 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
445 ok(compare_vec4(&dst_data
[0], +7.500e+1f
, +4.000e+1f
, -8.000e-1f
, +1.000e+0f
, 4096),
446 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
447 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
448 ok(compare_vec4(&dst_data
[1], +1.200e+2f
, +2.000e+1f
, -1.000e+0f
, +1.000e+0f
, 4096),
449 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
450 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
451 ok(compare_vec4(&dst_data
[2], +1.650e+2f
, +0.000e+0f
, -1.200e+0f
, +1.000e+0f
, 4096),
452 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
453 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
454 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
455 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
457 vp1
.dwSize
= sizeof(vp1
);
468 hr
= IDirect3DViewport3_SetViewport(viewport
, &vp1
);
469 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
471 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
472 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
474 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
475 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
476 ok(compare_vec4(&dst_data
[0], +1.100e+2f
, +6.800e+1f
, +7.000e+0f
, +1.000e+0f
, 4096),
477 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
478 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
479 ok(compare_vec4(&dst_data
[1], +1.170e+2f
, +6.600e+1f
, +8.000e+0f
, +1.000e+0f
, 4096),
480 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
481 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
482 ok(compare_vec4(&dst_data
[2], +1.240e+2f
, +6.400e+1f
, +9.000e+0f
, +1.000e+0f
, 4096),
483 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
484 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
485 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
486 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
488 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
489 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
491 IDirect3DVertexBuffer_Release(dst_vb
);
492 IDirect3DVertexBuffer_Release(src_vb
);
493 IDirect3DViewport3_Release(viewport
);
494 IDirect3D3_Release(d3d3
);
495 IDirect3DDevice3_Release(device
);
496 DestroyWindow(window
);
499 static void test_coop_level_create_device_window(void)
501 HWND focus_window
, device_window
;
505 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
506 0, 0, 640, 480, 0, 0, 0, 0);
507 if (!(ddraw
= create_ddraw()))
509 skip("Failed to create a ddraw object, skipping test.\n");
510 DestroyWindow(focus_window
);
514 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
515 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
516 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
517 ok(!device_window
, "Unexpected device window found.\n");
518 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
519 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
520 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
521 ok(!device_window
, "Unexpected device window found.\n");
522 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
523 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
524 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
525 ok(!device_window
, "Unexpected device window found.\n");
526 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
527 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
528 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
529 ok(!device_window
, "Unexpected device window found.\n");
530 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
531 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
532 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
533 ok(!device_window
, "Unexpected device window found.\n");
535 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
536 if (broken(hr
== DDERR_INVALIDPARAMS
))
538 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
539 IDirectDraw4_Release(ddraw
);
540 DestroyWindow(focus_window
);
544 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
545 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
546 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
547 ok(!device_window
, "Unexpected device window found.\n");
548 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
549 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
550 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
551 ok(!device_window
, "Unexpected device window found.\n");
553 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
554 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
555 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
556 ok(!device_window
, "Unexpected device window found.\n");
557 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
558 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
559 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
560 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
561 ok(!!device_window
, "Device window not found.\n");
563 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
564 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
565 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
566 ok(!device_window
, "Unexpected device window found.\n");
567 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
568 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
569 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
570 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
571 ok(!!device_window
, "Device window not found.\n");
573 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
574 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
575 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
576 ok(!device_window
, "Unexpected device window found.\n");
577 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
578 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
579 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
580 ok(!device_window
, "Unexpected device window found.\n");
581 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
582 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
583 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
584 ok(!device_window
, "Unexpected device window found.\n");
585 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
586 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
587 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
588 ok(!!device_window
, "Device window not found.\n");
590 IDirectDraw4_Release(ddraw
);
591 DestroyWindow(focus_window
);
594 static void test_clipper_blt(void)
596 IDirectDrawSurface4
*src_surface
, *dst_surface
;
597 RECT client_rect
, src_rect
, *rect
;
598 IDirectDrawClipper
*clipper
;
599 DDSURFACEDESC2 surface_desc
;
600 unsigned int i
, j
, x
, y
;
611 static const DWORD src_data
[] =
613 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
614 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
615 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
617 static const D3DCOLOR expected1
[] =
619 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
620 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
621 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
622 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
624 static const D3DCOLOR expected2
[] =
626 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
627 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
628 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
629 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
632 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
633 10, 10, 640, 480, 0, 0, 0, 0);
634 ShowWindow(window
, SW_SHOW
);
635 if (!(ddraw
= create_ddraw()))
637 skip("Failed to create a ddraw object, skipping test.\n");
638 DestroyWindow(window
);
642 ret
= GetClientRect(window
, &client_rect
);
643 ok(ret
, "Failed to get client rect.\n");
644 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
645 ok(ret
, "Failed to map client rect.\n");
647 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
648 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
650 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
651 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
652 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
653 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
654 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
655 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
656 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
657 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
658 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
659 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
660 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
661 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
662 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
663 ok(rgn_data
->rdh
.nCount
== 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
664 ok(rgn_data
->rdh
.nRgnSize
== 16, "Got unexpected region size %u.\n", rgn_data
->rdh
.nRgnSize
);
665 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
666 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
667 rgn_data
->rdh
.rcBound
.left
, rgn_data
->rdh
.rcBound
.top
,
668 rgn_data
->rdh
.rcBound
.right
, rgn_data
->rdh
.rcBound
.bottom
,
669 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
670 rect
= (RECT
*)&rgn_data
->Buffer
[0];
671 ok(EqualRect(rect
, &client_rect
),
672 "Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
673 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
674 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
675 HeapFree(GetProcessHeap(), 0, rgn_data
);
677 r1
= CreateRectRgn(0, 0, 320, 240);
678 ok(!!r1
, "Failed to create region.\n");
679 r2
= CreateRectRgn(320, 240, 640, 480);
680 ok(!!r2
, "Failed to create region.\n");
681 CombineRgn(r1
, r1
, r2
, RGN_OR
);
682 ret
= GetRegionData(r1
, 0, NULL
);
683 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
684 ret
= GetRegionData(r1
, ret
, rgn_data
);
685 ok(!!ret
, "Failed to get region data.\n");
690 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
691 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
692 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
693 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
694 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
695 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
697 HeapFree(GetProcessHeap(), 0, rgn_data
);
699 memset(&surface_desc
, 0, sizeof(surface_desc
));
700 surface_desc
.dwSize
= sizeof(surface_desc
);
701 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
702 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
703 surface_desc
.dwWidth
= 640;
704 surface_desc
.dwHeight
= 480;
705 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
706 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
707 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
708 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
709 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
710 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
712 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
713 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
714 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
715 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
717 memset(&fx
, 0, sizeof(fx
));
718 fx
.dwSize
= sizeof(fx
);
719 hr
= IDirectDrawSurface4_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
720 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
721 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
722 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
724 hr
= IDirectDrawSurface4_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
725 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
726 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
727 ptr
= surface_desc
.lpSurface
;
728 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
729 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
730 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
731 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
732 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
734 hr
= IDirectDrawSurface4_SetClipper(dst_surface
, clipper
);
735 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
737 SetRect(&src_rect
, 1, 1, 5, 2);
738 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
739 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
740 for (i
= 0; i
< 4; ++i
)
742 for (j
= 0; j
< 4; ++j
)
744 x
= 80 * ((2 * j
) + 1);
745 y
= 60 * ((2 * i
) + 1);
746 color
= get_surface_color(dst_surface
, x
, y
);
747 ok(compare_color(color
, expected1
[i
* 4 + j
], 1),
748 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
752 U5(fx
).dwFillColor
= 0xff0000ff;
753 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
754 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
755 for (i
= 0; i
< 4; ++i
)
757 for (j
= 0; j
< 4; ++j
)
759 x
= 80 * ((2 * j
) + 1);
760 y
= 60 * ((2 * i
) + 1);
761 color
= get_surface_color(dst_surface
, x
, y
);
762 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
763 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
767 hr
= IDirectDrawSurface4_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
768 ok(hr
== DDERR_BLTFASTCANTCLIP
, "Got unexpected hr %#x.\n", hr
);
770 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
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 DestroyWindow(window
);
775 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
776 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
777 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
778 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
779 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
780 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
781 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
782 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
783 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
784 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
785 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
786 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
788 IDirectDrawSurface4_Release(dst_surface
);
789 IDirectDrawSurface4_Release(src_surface
);
790 IDirectDrawClipper_Release(clipper
);
791 IDirectDraw4_Release(ddraw
);
794 static void test_coop_level_d3d_state(void)
796 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
797 IDirectDrawSurface4
*rt
, *surface
;
798 IDirect3DViewport3
*viewport
;
799 IDirect3DDevice3
*device
;
808 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
809 0, 0, 640, 480, 0, 0, 0, 0);
810 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
812 skip("Failed to create D3D device, skipping test.\n");
813 DestroyWindow(window
);
817 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
818 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
820 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
821 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
822 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
823 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
824 memset(&vp
, 0, sizeof(vp
));
825 vp
.dwSize
= sizeof(vp
);
832 vp
.dvClipWidth
= 2.0f
;
833 vp
.dvClipHeight
= 2.0f
;
836 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
837 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
839 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
840 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
841 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
842 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
843 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
844 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
845 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
846 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
847 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
848 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
849 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
850 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
851 color
= get_surface_color(rt
, 320, 240);
852 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
854 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
855 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
856 IDirect3D3_Release(d3d
);
857 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
858 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
859 hr
= IDirectDrawSurface4_IsLost(rt
);
860 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
861 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
862 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
863 IDirectDraw4_Release(ddraw
);
865 hr
= IDirect3DDevice3_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
= IDirect3DDevice3_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
= IDirect3DDevice3_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
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
875 ok(SUCCEEDED(hr
), "Failed to clear viewport, 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 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
880 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
881 IDirect3DViewport3_Release(viewport
);
882 IDirectDrawSurface4_Release(surface
);
883 IDirectDrawSurface4_Release(rt
);
884 IDirect3DDevice3_Release(device
);
885 DestroyWindow(window
);
888 static void test_surface_interface_mismatch(void)
890 IDirectDraw4
*ddraw
= NULL
;
891 IDirect3D3
*d3d
= NULL
;
892 IDirectDrawSurface4
*surface
= NULL
, *ds
;
893 IDirectDrawSurface3
*surface3
= NULL
;
894 IDirect3DDevice3
*device
= NULL
;
895 IDirect3DViewport3
*viewport
= NULL
;
896 DDSURFACEDESC2 surface_desc
;
903 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
905 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
906 0, 0, 640, 480, 0, 0, 0, 0);
908 if (!(ddraw
= create_ddraw()))
910 skip("Failed to create a ddraw object, skipping test.\n");
914 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
915 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
917 memset(&surface_desc
, 0, sizeof(surface_desc
));
918 surface_desc
.dwSize
= sizeof(surface_desc
);
919 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
920 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
921 surface_desc
.dwWidth
= 640;
922 surface_desc
.dwHeight
= 480;
924 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
925 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
927 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
928 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface3, hr %#x.\n", hr
);
930 hr
= IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
);
933 skip("Failed to get the IDirect3D7 interface, skipping test.\n");
937 memset(&z_fmt
, 0, sizeof(z_fmt
));
938 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
939 if (FAILED(hr
) || !z_fmt
.dwSize
)
941 skip("No depth buffer formats available, skipping test.\n");
945 memset(&surface_desc
, 0, sizeof(surface_desc
));
946 surface_desc
.dwSize
= sizeof(surface_desc
);
947 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
948 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
949 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
950 surface_desc
.dwWidth
= 640;
951 surface_desc
.dwHeight
= 480;
952 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
953 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
957 /* Using a different surface interface version still works */
958 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
959 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
960 refcount
= IDirectDrawSurface4_Release(ds
);
961 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
966 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface4
*)surface3
, &device
, NULL
);
967 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
971 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
972 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
973 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
974 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
975 memset(&vp
, 0, sizeof(vp
));
976 vp
.dwSize
= sizeof(vp
);
983 vp
.dvClipWidth
= 2.0f
;
984 vp
.dvClipHeight
= 2.0f
;
987 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
988 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
990 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
991 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
992 color
= get_surface_color(surface
, 320, 240);
993 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
998 IDirect3DDevice3_DeleteViewport(device
, viewport
);
999 IDirect3DViewport3_Release(viewport
);
1001 if (surface3
) IDirectDrawSurface3_Release(surface3
);
1002 if (surface
) IDirectDrawSurface4_Release(surface
);
1003 if (device
) IDirect3DDevice3_Release(device
);
1004 if (d3d
) IDirect3D3_Release(d3d
);
1005 if (ddraw
) IDirectDraw4_Release(ddraw
);
1006 DestroyWindow(window
);
1009 static void test_coop_level_threaded(void)
1011 struct create_window_thread_param p
;
1012 IDirectDraw4
*ddraw
;
1015 if (!(ddraw
= create_ddraw()))
1017 skip("Failed to create a ddraw object, skipping test.\n");
1020 create_window_thread(&p
);
1022 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1023 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1025 IDirectDraw4_Release(ddraw
);
1026 destroy_window_thread(&p
);
1029 static void test_depth_blit(void)
1038 { -1.0, 1.0, 0.50f
, 0xff00ff00},
1039 { 1.0, 1.0, 0.50f
, 0xff00ff00},
1040 { -1.0, -1.0, 0.50f
, 0xff00ff00},
1041 { 1.0, -1.0, 0.50f
, 0xff00ff00},
1043 static const D3DCOLOR expected_colors
[4][4] =
1045 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1046 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1047 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1048 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1050 DDSURFACEDESC2 ddsd_new
, ddsd_existing
;
1052 IDirect3DDevice3
*device
;
1053 IDirectDrawSurface4
*ds1
, *ds2
, *ds3
, *rt
;
1054 IDirect3DViewport3
*viewport
;
1055 D3DVIEWPORT2 vp_data
;
1056 RECT src_rect
, dst_rect
;
1061 IDirectDraw4
*ddraw
;
1066 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1067 0, 0, 640, 480, 0, 0, 0, 0);
1068 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1070 skip("Failed to create D3D device, skipping test.\n");
1071 DestroyWindow(window
);
1075 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1076 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
1077 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1078 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
1079 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
1080 ok(SUCCEEDED(hr
), "Failed to create a viewport, hr %#x.\n", hr
);
1081 IDirect3D3_Release(d3d
);
1083 ds1
= get_depth_stencil(device
);
1085 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1086 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1087 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1088 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1089 hr
= IDirectDrawSurface4_GetSurfaceDesc(ds1
, &ddsd_existing
);
1090 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1091 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1092 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1093 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1094 U4(ddsd_new
).ddpfPixelFormat
= U4(ddsd_existing
).ddpfPixelFormat
;
1095 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1096 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1097 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1098 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1099 IDirectDraw4_Release(ddraw
);
1101 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
1102 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1103 memset(&vp_data
, 0, sizeof(vp_data
));
1104 vp_data
.dwSize
= sizeof(vp_data
);
1105 vp_data
.dwWidth
= ddsd_existing
.dwWidth
;
1106 vp_data
.dwHeight
= ddsd_existing
.dwHeight
;
1107 vp_data
.dvMaxZ
= 1.0;
1108 vp_data
.dvClipX
= -1.0f
;
1109 vp_data
.dvClipWidth
= 2.0f
;
1110 vp_data
.dvClipY
= 1.0f
;
1111 vp_data
.dvClipHeight
= 2.0f
;
1112 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp_data
);
1113 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
1114 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1115 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
1117 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1118 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
1119 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1120 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
1121 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
1122 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
1124 U1(d3drect
).x1
= U2(d3drect
).y1
= 0;
1125 U3(d3drect
).x2
= vp_data
.dwWidth
; U4(d3drect
).y2
= vp_data
.dwHeight
;
1126 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
1127 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
1130 SetRect(&src_rect
, 0, 0, 320, 240);
1131 SetRect(&dst_rect
, 0, 0, 320, 240);
1132 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1133 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1134 /* Different locations. */
1135 SetRect(&src_rect
, 0, 0, 320, 240);
1136 SetRect(&dst_rect
, 320, 240, 640, 480);
1137 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1138 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1140 SetRect(&src_rect
, 0, 0, 320, 240);
1141 SetRect(&dst_rect
, 0, 0, 640, 480);
1142 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1143 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1145 SetRect(&src_rect
, 0, 480, 640, 0);
1146 SetRect(&dst_rect
, 0, 0, 640, 480);
1147 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1148 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1149 SetRect(&src_rect
, 0, 0, 640, 480);
1150 SetRect(&dst_rect
, 0, 480, 640, 0);
1151 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1152 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1153 /* Full, explicit. */
1154 SetRect(&src_rect
, 0, 0, 640, 480);
1155 SetRect(&dst_rect
, 0, 0, 640, 480);
1156 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1157 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1158 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1160 /* Depth blit inside a BeginScene / EndScene pair */
1161 hr
= IDirect3DDevice3_BeginScene(device
);
1162 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1163 /* From the current depth stencil */
1164 hr
= IDirectDrawSurface4_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1165 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1166 /* To the current depth stencil */
1167 hr
= IDirectDrawSurface4_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1168 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1169 /* Between unbound surfaces */
1170 hr
= IDirectDrawSurface4_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1171 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1172 hr
= IDirect3DDevice3_EndScene(device
);
1173 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1175 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1176 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1177 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1178 * a reliable result(z = 0.0) */
1179 memset(&fx
, 0, sizeof(fx
));
1180 fx
.dwSize
= sizeof(fx
);
1181 hr
= IDirectDrawSurface4_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1182 ok(SUCCEEDED(hr
), "Failed to clear the source z buffer, hr %#x.\n", hr
);
1184 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
1185 ok(SUCCEEDED(hr
), "Failed to clear the color and z buffers, hr %#x.\n", hr
);
1186 SetRect(&dst_rect
, 0, 0, 320, 240);
1187 hr
= IDirectDrawSurface4_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1188 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1189 IDirectDrawSurface4_Release(ds3
);
1190 IDirectDrawSurface4_Release(ds2
);
1191 IDirectDrawSurface4_Release(ds1
);
1193 hr
= IDirect3DDevice3_BeginScene(device
);
1194 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1195 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
1197 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1198 hr
= IDirect3DDevice3_EndScene(device
);
1199 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1201 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1202 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1203 for (i
= 0; i
< 4; ++i
)
1205 for (j
= 0; j
< 4; ++j
)
1207 unsigned int x
= 80 * ((2 * j
) + 1);
1208 unsigned int y
= 60 * ((2 * i
) + 1);
1209 color
= get_surface_color(rt
, x
, y
);
1210 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1211 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1214 IDirectDrawSurface4_Release(rt
);
1216 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
1217 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#x.\n", hr
);
1218 IDirect3DViewport3_Release(viewport
);
1219 IDirect3DDevice3_Release(device
);
1220 DestroyWindow(window
);
1223 static void test_texture_load_ckey(void)
1225 IDirectDraw4
*ddraw
;
1226 IDirectDrawSurface4
*src
;
1227 IDirectDrawSurface4
*dst
;
1228 IDirect3DTexture2
*src_tex
;
1229 IDirect3DTexture2
*dst_tex
;
1230 DDSURFACEDESC2 ddsd
;
1234 if (!(ddraw
= create_ddraw()))
1236 skip("Failed to create ddraw object, skipping test.\n");
1239 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1240 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1242 memset(&ddsd
, 0, sizeof(ddsd
));
1243 ddsd
.dwSize
= sizeof(ddsd
);
1244 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1245 ddsd
.dwHeight
= 128;
1247 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1248 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1249 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1250 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1251 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1252 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1254 hr
= IDirectDrawSurface4_QueryInterface(src
, &IID_IDirect3DTexture2
, (void **)&src_tex
);
1255 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get Direct3DTexture2 interface, hr %#x.\n", hr
);
1258 /* 64 bit ddraw does not support d3d */
1259 skip("Could not get Direct3DTexture2 interface, skipping texture::Load color keying tests.\n");
1260 IDirectDrawSurface4_Release(dst
);
1261 IDirectDrawSurface4_Release(src
);
1262 IDirectDraw4_Release(ddraw
);
1265 hr
= IDirectDrawSurface4_QueryInterface(dst
, &IID_IDirect3DTexture2
, (void **)&dst_tex
);
1266 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture2 interface, hr %#x.\n", hr
);
1268 /* No surface has a color key */
1269 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1270 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1271 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1272 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1273 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1274 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1275 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1277 /* Source surface has a color key */
1278 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1279 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1280 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1281 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1282 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1283 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1284 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1285 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1286 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1288 /* Both surfaces have a color key: Dest ckey is overwritten */
1289 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1290 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1291 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1292 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1293 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1294 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1295 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1296 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1297 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1299 /* Only the destination has a color key: It is not deleted */
1300 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1301 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1302 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1303 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1304 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1305 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1306 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1307 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1308 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1309 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1311 IDirect3DTexture2_Release(dst_tex
);
1312 IDirect3DTexture2_Release(src_tex
);
1313 IDirectDrawSurface4_Release(dst
);
1314 IDirectDrawSurface4_Release(src
);
1315 IDirectDraw4_Release(ddraw
);
1318 static ULONG
get_refcount(IUnknown
*test_iface
)
1320 IUnknown_AddRef(test_iface
);
1321 return IUnknown_Release(test_iface
);
1324 static void test_viewport_interfaces(void)
1326 IDirectDraw4
*ddraw
;
1328 HRESULT hr
, old_d3d_ref
;
1330 IDirect3DViewport
*viewport
;
1331 IDirect3DViewport2
*viewport2
;
1332 IDirect3DViewport3
*viewport3
;
1333 IDirectDrawGammaControl
*gamma
;
1336 if (!(ddraw
= create_ddraw()))
1338 skip("Failed to create ddraw object, skipping test.\n");
1341 hr
= IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
);
1342 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get d3d interface, hr %#x.\n", hr
);
1345 skip("Direct3D not available, skipping tests\n");
1346 IDirectDraw4_Release(ddraw
);
1349 old_d3d_ref
= get_refcount((IUnknown
*)d3d
);
1351 hr
= IDirect3D3_CreateViewport(d3d
, &viewport3
, NULL
);
1352 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1353 ref
= get_refcount((IUnknown
*)viewport3
);
1354 ok(ref
== 1, "Initial IDirect3DViewport3 refcount is %u\n", ref
);
1355 ref
= get_refcount((IUnknown
*)d3d
);
1356 ok(ref
== old_d3d_ref
, "IDirect3D3 refcount is %u\n", ref
);
1358 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1359 hr
= IDirect3DViewport2_QueryInterface(viewport3
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1360 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
1361 ok(gamma
== NULL
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1362 if (SUCCEEDED(hr
)) IDirectDrawGammaControl_Release(gamma
);
1363 /* NULL iid: Segfaults */
1365 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IDirect3DViewport
, (void **)&viewport
);
1366 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport, hr %#x.\n", hr
);
1369 ref
= get_refcount((IUnknown
*)viewport
);
1370 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
1371 ref
= get_refcount((IUnknown
*)viewport3
);
1372 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1373 IDirect3DViewport_Release(viewport
);
1377 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IDirect3DViewport3
, (void **)&viewport2
);
1378 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport3, hr %#x.\n", hr
);
1381 ref
= get_refcount((IUnknown
*)viewport2
);
1382 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
1383 ref
= get_refcount((IUnknown
*)viewport3
);
1384 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1385 IDirect3DViewport3_Release(viewport2
);
1388 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IUnknown
, (void **)&unknown
);
1389 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#x.\n", hr
);
1392 ref
= get_refcount((IUnknown
*)viewport3
);
1393 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1394 ref
= get_refcount(unknown
);
1395 ok(ref
== 2, "IUnknown refcount is %u\n", ref
);
1396 IUnknown_Release(unknown
);
1399 IDirect3DViewport3_Release(viewport3
);
1400 IDirect3D3_Release(d3d
);
1401 IDirectDraw4_Release(ddraw
);
1404 static void test_zenable(void)
1406 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1409 struct vec4 position
;
1414 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1415 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1416 {{640.0f
, 480.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1417 {{640.0f
, 0.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1419 IDirect3DViewport3
*viewport
;
1420 IDirect3DDevice3
*device
;
1421 IDirectDrawSurface4
*rt
;
1430 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1431 0, 0, 640, 480, 0, 0, 0, 0);
1432 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1434 skip("Failed to create D3D device, skipping test.\n");
1435 DestroyWindow(window
);
1439 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1440 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1441 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
1442 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1444 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
1445 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
1446 memset(&vp
, 0, sizeof(vp
));
1447 vp
.dwSize
= sizeof(vp
);
1454 vp
.dvClipWidth
= 2.0f
;
1455 vp
.dvClipHeight
= 2.0f
;
1458 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
1459 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
1460 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1461 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1463 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1464 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
1466 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
1467 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1468 hr
= IDirect3DDevice3_BeginScene(device
);
1469 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1470 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
, tquad
, 4, 0);
1471 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1472 hr
= IDirect3DDevice3_EndScene(device
);
1473 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1475 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1476 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1477 for (i
= 0; i
< 4; ++i
)
1479 for (j
= 0; j
< 4; ++j
)
1481 x
= 80 * ((2 * j
) + 1);
1482 y
= 60 * ((2 * i
) + 1);
1483 color
= get_surface_color(rt
, x
, y
);
1484 ok(compare_color(color
, 0x0000ff00, 1),
1485 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1488 IDirectDrawSurface4_Release(rt
);
1490 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
1491 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
1492 IDirect3DViewport3_Release(viewport
);
1493 IDirect3D3_Release(d3d
);
1494 IDirect3DDevice3_Release(device
);
1495 DestroyWindow(window
);
1498 static void test_ck_rgba(void)
1500 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1503 struct vec4 position
;
1504 struct vec2 texcoord
;
1508 {{ 0.0f
, 480.0f
, 0.25f
, 1.0f
}, {0.0f
, 0.0f
}},
1509 {{ 0.0f
, 0.0f
, 0.25f
, 1.0f
}, {0.0f
, 1.0f
}},
1510 {{640.0f
, 480.0f
, 0.25f
, 1.0f
}, {1.0f
, 0.0f
}},
1511 {{640.0f
, 0.0f
, 0.25f
, 1.0f
}, {1.0f
, 1.0f
}},
1512 {{ 0.0f
, 480.0f
, 0.75f
, 1.0f
}, {0.0f
, 0.0f
}},
1513 {{ 0.0f
, 0.0f
, 0.75f
, 1.0f
}, {0.0f
, 1.0f
}},
1514 {{640.0f
, 480.0f
, 0.75f
, 1.0f
}, {1.0f
, 0.0f
}},
1515 {{640.0f
, 0.0f
, 0.75f
, 1.0f
}, {1.0f
, 1.0f
}},
1519 D3DCOLOR fill_color
;
1527 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x000000ff},
1528 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x000000ff},
1529 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00},
1530 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1531 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00807f00},
1532 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x0000ff00},
1533 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00},
1534 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1537 IDirectDrawSurface4
*surface
;
1538 IDirect3DViewport3
*viewport
;
1539 DDSURFACEDESC2 surface_desc
;
1540 IDirect3DTexture2
*texture
;
1541 IDirect3DDevice3
*device
;
1542 IDirectDrawSurface4
*rt
;
1543 IDirectDraw4
*ddraw
;
1552 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1553 0, 0, 640, 480, 0, 0, 0, 0);
1554 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1556 skip("Failed to create D3D device, skipping test.\n");
1557 DestroyWindow(window
);
1561 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1562 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1564 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
1565 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1566 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
1567 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
1568 memset(&vp
, 0, sizeof(vp
));
1569 vp
.dwSize
= sizeof(vp
);
1576 vp
.dvClipWidth
= 2.0f
;
1577 vp
.dvClipHeight
= 2.0f
;
1580 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
1581 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
1582 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1583 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1584 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1585 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1587 IDirect3D3_Release(d3d
);
1589 memset(&surface_desc
, 0, sizeof(surface_desc
));
1590 surface_desc
.dwSize
= sizeof(surface_desc
);
1591 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1592 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1593 surface_desc
.dwWidth
= 256;
1594 surface_desc
.dwHeight
= 256;
1595 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1596 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1597 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1598 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1599 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1600 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1601 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1602 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1603 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1604 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1605 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1606 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1607 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1609 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
1610 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1611 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1612 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1613 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1614 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1616 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1617 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1619 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
1621 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1622 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1623 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1624 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1626 memset(&fx
, 0, sizeof(fx
));
1627 fx
.dwSize
= sizeof(fx
);
1628 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1629 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1630 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1632 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
,
1633 D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
1634 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1635 hr
= IDirect3DDevice3_BeginScene(device
);
1636 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1637 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1638 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1639 hr
= IDirect3DDevice3_EndScene(device
);
1640 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1642 color
= get_surface_color(rt
, 320, 240);
1644 todo_wine
ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1645 tests
[i
].result1
, i
, color
);
1647 ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1648 tests
[i
].result1
, i
, color
);
1650 U5(fx
).dwFillColor
= 0xff0000ff;
1651 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1652 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1654 hr
= IDirect3DDevice3_BeginScene(device
);
1655 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1656 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[4], 4, 0);
1657 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1658 hr
= IDirect3DDevice3_EndScene(device
);
1659 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1661 /* This tests that fragments that are masked out by the color key are
1662 * discarded, instead of just fully transparent. */
1663 color
= get_surface_color(rt
, 320, 240);
1665 todo_wine
ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1666 tests
[i
].result2
, i
, color
);
1668 ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1669 tests
[i
].result2
, i
, color
);
1672 IDirectDrawSurface4_Release(rt
);
1673 IDirect3DTexture2_Release(texture
);
1674 IDirectDrawSurface4_Release(surface
);
1675 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
1676 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
1677 IDirect3DViewport3_Release(viewport
);
1678 IDirectDraw4_Release(ddraw
);
1679 IDirect3DDevice3_Release(device
);
1680 DestroyWindow(window
);
1685 test_process_vertices();
1686 test_coop_level_create_device_window();
1688 test_coop_level_d3d_state();
1689 test_surface_interface_mismatch();
1690 test_coop_level_threaded();
1692 test_texture_load_ckey();
1693 test_viewport_interfaces();