2 * Copyright 2011-2012 Henri Verbeet for CodeWeavers
3 * Copyright 2012-2013 Stefan Dösinger 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"
40 struct create_window_thread_param
43 HANDLE window_created;
44 HANDLE destroy_window;
48 static BOOL compare_float(float f, float g, unsigned int ulps)
58 if (abs(x - y) > ulps)
64 static BOOL compare_vec4(struct vec4 *vec, float x, float y, float z, float w, unsigned int ulps)
66 return compare_float(vec->x, x, ulps)
67 && compare_float(vec->y, y, ulps)
68 && compare_float(vec->z, z, ulps)
69 && compare_float(vec->w, w, ulps);
72 static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
74 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
76 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
78 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
80 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
84 static DWORD WINAPI create_window_thread_proc(void *param)
86 struct create_window_thread_param *p = param;
90 p->window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
91 0, 0, 640, 480, 0, 0, 0, 0);
92 ret = SetEvent(p->window_created);
93 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
99 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
100 DispatchMessage(&msg);
101 res = WaitForSingleObject(p->destroy_window, 100);
102 if (res == WAIT_OBJECT_0)
104 if (res != WAIT_TIMEOUT)
106 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
111 DestroyWindow(p->window);
116 static void create_window_thread(struct create_window_thread_param *p)
120 p->window_created = CreateEvent(NULL, FALSE, FALSE, NULL);
121 ok(!!p->window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
122 p->destroy_window = CreateEvent(NULL, FALSE, FALSE, NULL);
123 ok(!!p->destroy_window, "CreateEvent failed, last error %#x.\n", GetLastError());
124 p->thread = CreateThread(NULL, 0, create_window_thread_proc, p, 0, &tid);
125 ok(!!p->thread, "Failed to create thread, last error %#x.\n", GetLastError());
126 res = WaitForSingleObject(p->window_created, INFINITE);
127 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
130 static void destroy_window_thread(struct create_window_thread_param *p)
132 SetEvent(p->destroy_window);
133 WaitForSingleObject(p->thread, INFINITE);
134 CloseHandle(p->destroy_window);
135 CloseHandle(p->window_created);
136 CloseHandle(p->thread);
139 static IDirectDrawSurface4 *get_depth_stencil(IDirect3DDevice3 *device)
141 IDirectDrawSurface4 *rt, *ret;
142 DDSCAPS2 caps = {DDSCAPS_ZBUFFER, 0, 0, 0};
145 hr = IDirect3DDevice3_GetRenderTarget(device, &rt);
146 ok(SUCCEEDED(hr), "Failed to get the render target, hr %#x.\n", hr);
147 hr = IDirectDrawSurface4_GetAttachedSurface(rt, &caps, &ret);
148 ok(SUCCEEDED(hr) || hr == DDERR_NOTFOUND, "Failed to get the z buffer, hr %#x.\n", hr);
149 IDirectDrawSurface4_Release(rt);
153 static D3DCOLOR get_surface_color(IDirectDrawSurface4 *surface, UINT x, UINT y)
155 RECT rect = {x, y, x + 1, y + 1};
156 DDSURFACEDESC2 surface_desc;
160 memset(&surface_desc, 0, sizeof(surface_desc));
161 surface_desc.dwSize = sizeof(surface_desc);
163 hr = IDirectDrawSurface4_Lock(surface, &rect, &surface_desc, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
164 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
168 color = *((DWORD *)surface_desc.lpSurface) & 0x00ffffff;
170 hr = IDirectDrawSurface4_Unlock(surface, &rect);
171 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
176 static HRESULT CALLBACK enum_z_fmt(DDPIXELFORMAT *format, void *ctx)
178 DDPIXELFORMAT *z_fmt = ctx;
180 if (U1(*format).dwZBufferBitDepth > U1(*z_fmt).dwZBufferBitDepth)
186 static IDirectDraw4 *create_ddraw(void)
188 IDirectDraw4 *ddraw4;
192 if (FAILED(DirectDrawCreate(NULL, &ddraw1, NULL)))
195 hr = IDirectDraw_QueryInterface(ddraw1, &IID_IDirectDraw4, (void **)&ddraw4);
196 IDirectDraw_Release(ddraw1);
203 static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level)
205 IDirectDrawSurface4 *surface, *ds;
206 IDirect3DDevice3 *device = NULL;
207 DDSURFACEDESC2 surface_desc;
208 IDirectDraw4 *ddraw4;
213 if (!(ddraw4 = create_ddraw()))
216 hr = IDirectDraw4_SetCooperativeLevel(ddraw4, window, coop_level);
217 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
219 memset(&surface_desc, 0, sizeof(surface_desc));
220 surface_desc.dwSize = sizeof(surface_desc);
221 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
222 surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
223 surface_desc.dwWidth = 640;
224 surface_desc.dwHeight = 480;
226 hr = IDirectDraw4_CreateSurface(ddraw4, &surface_desc, &surface, NULL);
227 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
229 if (coop_level & DDSCL_NORMAL)
231 IDirectDrawClipper *clipper;
233 hr = IDirectDraw4_CreateClipper(ddraw4, 0, &clipper, NULL);
234 ok(SUCCEEDED(hr), "Failed to create clipper, hr %#x.\n", hr);
235 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
236 ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
237 hr = IDirectDrawSurface4_SetClipper(surface, clipper);
238 ok(SUCCEEDED(hr), "Failed to set surface clipper, hr %#x.\n", hr);
239 IDirectDrawClipper_Release(clipper);
242 hr = IDirectDraw4_QueryInterface(ddraw4, &IID_IDirect3D3, (void **)&d3d3);
243 IDirectDraw4_Release(ddraw4);
246 IDirectDrawSurface4_Release(surface);
250 memset(&z_fmt, 0, sizeof(z_fmt));
251 hr = IDirect3D3_EnumZBufferFormats(d3d3, &IID_IDirect3DHALDevice, enum_z_fmt, &z_fmt);
252 if (FAILED(hr) || !z_fmt.dwSize)
254 IDirect3D3_Release(d3d3);
255 IDirectDrawSurface4_Release(surface);
259 memset(&surface_desc, 0, sizeof(surface_desc));
260 surface_desc.dwSize = sizeof(surface_desc);
261 surface_desc.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT;
262 surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
263 U4(surface_desc).ddpfPixelFormat = z_fmt;
264 surface_desc.dwWidth = 640;
265 surface_desc.dwHeight = 480;
266 hr = IDirectDraw4_CreateSurface(ddraw4, &surface_desc, &ds, NULL);
267 ok(SUCCEEDED(hr), "Failed to create depth buffer, hr %#x.\n", hr);
270 IDirect3D3_Release(d3d3);
271 IDirectDrawSurface4_Release(surface);
275 hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
276 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x.\n", hr);
277 IDirectDrawSurface4_Release(ds);
280 IDirect3D3_Release(d3d3);
281 IDirectDrawSurface4_Release(surface);
285 hr = IDirect3D3_CreateDevice(d3d3, &IID_IDirect3DHALDevice, surface, &device, NULL);
286 IDirect3D3_Release(d3d3);
287 IDirectDrawSurface4_Release(surface);
294 static IDirect3DViewport3 *create_viewport(IDirect3DDevice3 *device, UINT x, UINT y, UINT w, UINT h)
296 IDirect3DViewport3 *viewport;
301 hr = IDirect3DDevice3_GetDirect3D(device, &d3d);
302 ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
303 hr = IDirect3D3_CreateViewport(d3d, &viewport, NULL);
304 ok(SUCCEEDED(hr), "Failed to create viewport, hr %#x.\n", hr);
305 hr = IDirect3DDevice3_AddViewport(device, viewport);
306 ok(SUCCEEDED(hr), "Failed to add viewport, hr %#x.\n", hr);
307 memset(&vp, 0, sizeof(vp));
308 vp.dwSize = sizeof(vp);
315 vp.dvClipWidth = 2.0f;
316 vp.dvClipHeight = 2.0f;
319 hr = IDirect3DViewport3_SetViewport2(viewport, &vp);
320 ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x.\n", hr);
321 IDirect3D3_Release(d3d);
326 static void destroy_viewport(IDirect3DDevice3 *device, IDirect3DViewport3 *viewport)
330 hr = IDirect3DDevice3_DeleteViewport(device, viewport);
331 ok(SUCCEEDED(hr), "Failed to delete viewport, hr %#x.\n", hr);
332 IDirect3DViewport3_Release(viewport);
335 static const UINT *expect_messages;
337 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
339 if (expect_messages && message == *expect_messages)
342 return DefWindowProcA(hwnd, message, wparam, lparam);
345 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
346 * interface. This prevents subsequent SetCooperativeLevel() calls on a
347 * different window from failing with DDERR_HWNDALREADYSET. */
348 static void fix_wndproc(HWND window, LONG_PTR proc)
353 if (!(ddraw = create_ddraw()))
356 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
357 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
358 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
359 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
360 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
362 IDirectDraw4_Release(ddraw);
365 static void test_process_vertices(void)
367 IDirect3DVertexBuffer *src_vb, *dst_vb;
368 IDirect3DViewport3 *viewport;
369 D3DVERTEXBUFFERDESC vb_desc;
370 IDirect3DDevice3 *device;
371 struct vec3 *src_data;
372 struct vec4 *dst_data;
379 static D3DMATRIX identity =
381 1.0f, 0.0f, 0.0f, 0.0f,
382 0.0f, 1.0f, 0.0f, 0.0f,
383 0.0f, 0.0f, 1.0f, 0.0f,
384 0.0f, 0.0f, 0.0f, 1.0f,
386 static D3DMATRIX projection =
388 1.0f, 0.0f, 0.0f, 0.0f,
389 0.0f, 1.0f, 0.0f, 0.0f,
390 0.0f, 0.0f, 1.0f, 0.0f,
391 6.0f, 7.0f, 8.0f, 1.0f,
394 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
395 0, 0, 640, 480, 0, 0, 0, 0);
396 if (!(device = create_device(window, DDSCL_NORMAL)))
398 skip("Failed to create a 3D device, skipping test.\n");
399 DestroyWindow(window);
403 hr = IDirect3DDevice3_GetDirect3D(device, &d3d3);
404 ok(SUCCEEDED(hr), "Failed to get Direct3D3 interface, hr %#x.\n", hr);
406 memset(&vb_desc, 0, sizeof(vb_desc));
407 vb_desc.dwSize = sizeof(vb_desc);
408 vb_desc.dwFVF = D3DFVF_XYZ;
409 vb_desc.dwNumVertices = 3;
410 hr = IDirect3D3_CreateVertexBuffer(d3d3, &vb_desc, &src_vb, 0, NULL);
411 ok(SUCCEEDED(hr), "Failed to create source vertex buffer, hr %#x.\n", hr);
413 hr = IDirect3DVertexBuffer_Lock(src_vb, DDLOCK_WRITEONLY, (void **)&src_data, NULL);
414 ok(SUCCEEDED(hr), "Failed to lock source vertex buffer, hr %#x.\n", hr);
415 src_data[0].x = -1.0f;
416 src_data[0].y = -1.0f;
417 src_data[0].z = -1.0f;
418 src_data[1].x = 0.0f;
419 src_data[1].y = 0.0f;
420 src_data[1].z = 0.0f;
421 src_data[2].x = 1.0f;
422 src_data[2].y = 1.0f;
423 src_data[2].z = 1.0f;
424 hr = IDirect3DVertexBuffer_Unlock(src_vb);
425 ok(SUCCEEDED(hr), "Failed to unlock source vertex buffer, hr %#x.\n", hr);
427 memset(&vb_desc, 0, sizeof(vb_desc));
428 vb_desc.dwSize = sizeof(vb_desc);
429 vb_desc.dwFVF = D3DFVF_XYZRHW;
430 vb_desc.dwNumVertices = 3;
431 hr = IDirect3D3_CreateVertexBuffer(d3d3, &vb_desc, &dst_vb, 0, NULL);
432 ok(SUCCEEDED(hr), "Failed to create destination vertex buffer, hr %#x.\n", hr);
434 hr = IDirect3D3_CreateViewport(d3d3, &viewport, NULL);
435 ok(SUCCEEDED(hr), "Failed to create viewport, hr %#x.\n", hr);
436 hr = IDirect3DDevice3_AddViewport(device, viewport);
437 ok(SUCCEEDED(hr), "Failed to add viewport, hr %#x.\n", hr);
438 vp2.dwSize = sizeof(vp2);
445 vp2.dvClipWidth = 4.0f;
446 vp2.dvClipHeight = 5.0f;
449 hr = IDirect3DViewport3_SetViewport2(viewport, &vp2);
450 ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x.\n", hr);
451 hr = IDirect3DDevice3_SetCurrentViewport(device, viewport);
452 ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
454 hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &identity);
455 ok(SUCCEEDED(hr), "Failed to set world transformation, hr %#x.\n", hr);
456 hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &identity);
457 ok(SUCCEEDED(hr), "Failed to set view transformation, hr %#x.\n", hr);
458 hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &identity);
459 ok(SUCCEEDED(hr), "Failed to set projection transformation, hr %#x.\n", hr);
461 hr = IDirect3DVertexBuffer_ProcessVertices(dst_vb, D3DVOP_TRANSFORM, 0, 3, src_vb, 0, device, 0);
462 ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
464 hr = IDirect3DVertexBuffer_Lock(dst_vb, DDLOCK_READONLY, (void **)&dst_data, NULL);
465 ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
466 ok(compare_vec4(&dst_data[0], -6.500e+1f, +1.800e+2f, +2.000e-1f, +1.000e+0f, 4096),
467 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
468 dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
469 ok(compare_vec4(&dst_data[1], -4.000e+1f, +1.400e+2f, +4.000e-1f, +1.000e+0f, 4096),
470 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
471 dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
472 ok(compare_vec4(&dst_data[2], -1.500e+1f, +1.000e+2f, +6.000e-1f, +1.000e+0f, 4096),
473 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
474 dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
475 hr = IDirect3DVertexBuffer_Unlock(dst_vb);
476 ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
478 hr = IDirect3DDevice3_MultiplyTransform(device, D3DTRANSFORMSTATE_PROJECTION, &projection);
479 ok(SUCCEEDED(hr), "Failed to set projection transformation, hr %#x.\n", hr);
481 hr = IDirect3DVertexBuffer_ProcessVertices(dst_vb, D3DVOP_TRANSFORM, 0, 3, src_vb, 0, device, 0);
482 ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
484 hr = IDirect3DVertexBuffer_Lock(dst_vb, DDLOCK_READONLY, (void **)&dst_data, NULL);
485 ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
486 ok(compare_vec4(&dst_data[0], +8.500e+1f, -1.000e+2f, +1.800e+0f, +1.000e+0f, 4096),
487 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
488 dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
489 ok(compare_vec4(&dst_data[1], +1.100e+2f, -1.400e+2f, +2.000e+0f, +1.000e+0f, 4096),
490 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
491 dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
492 ok(compare_vec4(&dst_data[2], +1.350e+2f, -1.800e+2f, +2.200e+0f, +1.000e+0f, 4096),
493 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
494 dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
495 hr = IDirect3DVertexBuffer_Unlock(dst_vb);
496 ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
498 vp2.dwSize = sizeof(vp2);
505 vp2.dvClipWidth = 2.0f;
506 vp2.dvClipHeight = 4.0f;
509 hr = IDirect3DViewport3_SetViewport2(viewport, &vp2);
510 ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x.\n", hr);
512 hr = IDirect3DVertexBuffer_ProcessVertices(dst_vb, D3DVOP_TRANSFORM, 0, 3, src_vb, 0, device, 0);
513 ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
515 hr = IDirect3DVertexBuffer_Lock(dst_vb, DDLOCK_READONLY, (void **)&dst_data, NULL);
516 ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
517 ok(compare_vec4(&dst_data[0], +7.500e+1f, +4.000e+1f, -8.000e-1f, +1.000e+0f, 4096),
518 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
519 dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
520 ok(compare_vec4(&dst_data[1], +1.200e+2f, +2.000e+1f, -1.000e+0f, +1.000e+0f, 4096),
521 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
522 dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
523 ok(compare_vec4(&dst_data[2], +1.650e+2f, +0.000e+0f, -1.200e+0f, +1.000e+0f, 4096),
524 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
525 dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
526 hr = IDirect3DVertexBuffer_Unlock(dst_vb);
527 ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
529 vp1.dwSize = sizeof(vp1);
540 hr = IDirect3DViewport3_SetViewport(viewport, &vp1);
541 ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x.\n", hr);
543 hr = IDirect3DVertexBuffer_ProcessVertices(dst_vb, D3DVOP_TRANSFORM, 0, 3, src_vb, 0, device, 0);
544 ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
546 hr = IDirect3DVertexBuffer_Lock(dst_vb, DDLOCK_READONLY, (void **)&dst_data, NULL);
547 ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
548 ok(compare_vec4(&dst_data[0], +1.100e+2f, +6.800e+1f, +7.000e+0f, +1.000e+0f, 4096),
549 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
550 dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
551 ok(compare_vec4(&dst_data[1], +1.170e+2f, +6.600e+1f, +8.000e+0f, +1.000e+0f, 4096),
552 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
553 dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
554 ok(compare_vec4(&dst_data[2], +1.240e+2f, +6.400e+1f, +9.000e+0f, +1.000e+0f, 4096),
555 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
556 dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
557 hr = IDirect3DVertexBuffer_Unlock(dst_vb);
558 ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
560 hr = IDirect3DDevice3_DeleteViewport(device, viewport);
561 ok(SUCCEEDED(hr), "Failed to delete viewport, hr %#x.\n", hr);
563 IDirect3DVertexBuffer_Release(dst_vb);
564 IDirect3DVertexBuffer_Release(src_vb);
565 IDirect3DViewport3_Release(viewport);
566 IDirect3D3_Release(d3d3);
567 IDirect3DDevice3_Release(device);
568 DestroyWindow(window);
571 static void test_coop_level_create_device_window(void)
573 HWND focus_window, device_window;
577 focus_window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
578 0, 0, 640, 480, 0, 0, 0, 0);
579 if (!(ddraw = create_ddraw()))
581 skip("Failed to create a ddraw object, skipping test.\n");
582 DestroyWindow(focus_window);
586 hr = IDirectDraw4_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 = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW);
591 ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
592 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
593 ok(!device_window, "Unexpected device window found.\n");
594 hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_NORMAL);
595 ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
596 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
597 ok(!device_window, "Unexpected device window found.\n");
598 hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_NORMAL | DDSCL_FULLSCREEN);
599 ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
600 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
601 ok(!device_window, "Unexpected device window found.\n");
602 hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
603 ok(hr == DDERR_NOFOCUSWINDOW || broken(hr == DDERR_INVALIDPARAMS), "Got unexpected hr %#x.\n", hr);
604 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
605 ok(!device_window, "Unexpected device window found.\n");
607 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
608 if (broken(hr == DDERR_INVALIDPARAMS))
610 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
611 IDirectDraw4_Release(ddraw);
612 DestroyWindow(focus_window);
616 hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
617 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
618 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
619 ok(!device_window, "Unexpected device window found.\n");
620 hr = IDirectDraw4_SetCooperativeLevel(ddraw, focus_window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
621 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
622 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
623 ok(!device_window, "Unexpected device window found.\n");
625 hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
626 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
627 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
628 ok(!device_window, "Unexpected device window found.\n");
629 hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_SETFOCUSWINDOW
630 | DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
631 ok(hr == DDERR_NOHWND, "Got unexpected hr %#x.\n", hr);
632 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
633 ok(!!device_window, "Device window not found.\n");
635 hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
636 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
637 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
638 ok(!device_window, "Unexpected device window found.\n");
639 hr = IDirectDraw4_SetCooperativeLevel(ddraw, focus_window, DDSCL_SETFOCUSWINDOW
640 | DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
641 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
642 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
643 ok(!!device_window, "Device window not found.\n");
645 hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
646 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
647 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
648 ok(!device_window, "Unexpected device window found.\n");
649 hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
650 ok(hr == DDERR_NOFOCUSWINDOW, "Got unexpected hr %#x.\n", hr);
651 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
652 ok(!device_window, "Unexpected device window found.\n");
653 hr = IDirectDraw4_SetCooperativeLevel(ddraw, focus_window, DDSCL_SETFOCUSWINDOW);
654 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
655 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
656 ok(!device_window, "Unexpected device window found.\n");
657 hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
658 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
659 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
660 ok(!!device_window, "Device window not found.\n");
662 IDirectDraw4_Release(ddraw);
663 DestroyWindow(focus_window);
666 static void test_clipper_blt(void)
668 IDirectDrawSurface4 *src_surface, *dst_surface;
669 RECT client_rect, src_rect;
670 IDirectDrawClipper *clipper;
671 DDSURFACEDESC2 surface_desc;
672 unsigned int i, j, x, y;
683 static const DWORD src_data[] =
685 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
686 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
687 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
689 static const D3DCOLOR expected1[] =
691 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
692 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
693 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
694 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
696 static const D3DCOLOR expected2[] =
698 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
699 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
700 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
701 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
704 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
705 10, 10, 640, 480, 0, 0, 0, 0);
706 ShowWindow(window, SW_SHOW);
707 if (!(ddraw = create_ddraw()))
709 skip("Failed to create a ddraw object, skipping test.\n");
710 DestroyWindow(window);
714 ret = GetClientRect(window, &client_rect);
715 ok(ret, "Failed to get client rect.\n");
716 ret = MapWindowPoints(window, NULL, (POINT *)&client_rect, 2);
717 ok(ret, "Failed to map client rect.\n");
719 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
720 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
722 hr = IDirectDraw4_CreateClipper(ddraw, 0, &clipper, NULL);
723 ok(SUCCEEDED(hr), "Failed to create clipper, hr %#x.\n", hr);
724 hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
725 ok(hr == DDERR_NOCLIPLIST, "Got unexpected hr %#x.\n", hr);
726 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
727 ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
728 hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
729 ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr);
730 rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
731 hr = IDirectDrawClipper_GetClipList(clipper, NULL, rgn_data, &ret);
732 ok(SUCCEEDED(hr), "Failed to get clip list, hr %#x.\n", hr);
733 ok(rgn_data->rdh.dwSize == sizeof(rgn_data->rdh), "Got unexpected structure size %#x.\n", rgn_data->rdh.dwSize);
734 ok(rgn_data->rdh.iType == RDH_RECTANGLES, "Got unexpected type %#x.\n", rgn_data->rdh.iType);
735 ok(rgn_data->rdh.nCount >= 1, "Got unexpected count %u.\n", rgn_data->rdh.nCount);
736 ok(EqualRect(&rgn_data->rdh.rcBound, &client_rect),
737 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
738 rgn_data->rdh.rcBound.left, rgn_data->rdh.rcBound.top,
739 rgn_data->rdh.rcBound.right, rgn_data->rdh.rcBound.bottom,
740 client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
741 HeapFree(GetProcessHeap(), 0, rgn_data);
743 r1 = CreateRectRgn(0, 0, 320, 240);
744 ok(!!r1, "Failed to create region.\n");
745 r2 = CreateRectRgn(320, 240, 640, 480);
746 ok(!!r2, "Failed to create region.\n");
747 CombineRgn(r1, r1, r2, RGN_OR);
748 ret = GetRegionData(r1, 0, NULL);
749 rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
750 ret = GetRegionData(r1, ret, rgn_data);
751 ok(!!ret, "Failed to get region data.\n");
756 hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
757 ok(hr == DDERR_CLIPPERISUSINGHWND, "Got unexpected hr %#x.\n", hr);
758 hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL);
759 ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
760 hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
761 ok(SUCCEEDED(hr), "Failed to set clip list, hr %#x.\n", hr);
763 HeapFree(GetProcessHeap(), 0, rgn_data);
765 memset(&surface_desc, 0, sizeof(surface_desc));
766 surface_desc.dwSize = sizeof(surface_desc);
767 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
768 surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
769 surface_desc.dwWidth = 640;
770 surface_desc.dwHeight = 480;
771 U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
772 U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB;
773 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32;
774 U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0x00ff0000;
775 U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00;
776 U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff;
778 hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &src_surface, NULL);
779 ok(SUCCEEDED(hr), "Failed to create source surface, hr %#x.\n", hr);
780 hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &dst_surface, NULL);
781 ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr);
783 memset(&fx, 0, sizeof(fx));
784 fx.dwSize = sizeof(fx);
785 hr = IDirectDrawSurface4_Blt(src_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
786 ok(SUCCEEDED(hr), "Failed to clear source surface, hr %#x.\n", hr);
787 hr = IDirectDrawSurface4_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
788 ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
790 hr = IDirectDrawSurface4_Lock(src_surface, NULL, &surface_desc, DDLOCK_WAIT, NULL);
791 ok(SUCCEEDED(hr), "Failed to lock source surface, hr %#x.\n", hr);
792 ok(U1(surface_desc).lPitch == 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc).lPitch);
793 ptr = surface_desc.lpSurface;
794 memcpy(&ptr[ 0], &src_data[ 0], 6 * sizeof(DWORD));
795 memcpy(&ptr[ 640], &src_data[ 6], 6 * sizeof(DWORD));
796 memcpy(&ptr[1280], &src_data[12], 6 * sizeof(DWORD));
797 hr = IDirectDrawSurface4_Unlock(src_surface, NULL);
798 ok(SUCCEEDED(hr), "Failed to unlock source surface, hr %#x.\n", hr);
800 hr = IDirectDrawSurface4_SetClipper(dst_surface, clipper);
801 ok(SUCCEEDED(hr), "Failed to set clipper, hr %#x.\n", hr);
803 SetRect(&src_rect, 1, 1, 5, 2);
804 hr = IDirectDrawSurface4_Blt(dst_surface, NULL, src_surface, &src_rect, DDBLT_WAIT, NULL);
805 ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
806 for (i = 0; i < 4; ++i)
808 for (j = 0; j < 4; ++j)
810 x = 80 * ((2 * j) + 1);
811 y = 60 * ((2 * i) + 1);
812 color = get_surface_color(dst_surface, x, y);
813 ok(compare_color(color, expected1[i * 4 + j], 1),
814 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1[i * 4 + j], x, y, color);
818 U5(fx).dwFillColor = 0xff0000ff;
819 hr = IDirectDrawSurface4_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
820 ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
821 for (i = 0; i < 4; ++i)
823 for (j = 0; j < 4; ++j)
825 x = 80 * ((2 * j) + 1);
826 y = 60 * ((2 * i) + 1);
827 color = get_surface_color(dst_surface, x, y);
828 ok(compare_color(color, expected2[i * 4 + j], 1),
829 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2[i * 4 + j], x, y, color);
833 hr = IDirectDrawSurface4_BltFast(dst_surface, 0, 0, src_surface, NULL, DDBLTFAST_WAIT);
834 ok(hr == DDERR_BLTFASTCANTCLIP, "Got unexpected hr %#x.\n", hr);
836 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
837 ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
838 hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
839 ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr);
840 DestroyWindow(window);
841 hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
842 ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
843 hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL);
844 ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
845 hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
846 ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr);
847 hr = IDirectDrawClipper_SetClipList(clipper, NULL, 0);
848 ok(SUCCEEDED(hr), "Failed to set clip list, hr %#x.\n", hr);
849 hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
850 ok(hr == DDERR_NOCLIPLIST, "Got unexpected hr %#x.\n", hr);
851 hr = IDirectDrawSurface4_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
852 ok(hr == DDERR_NOCLIPLIST, "Got unexpected hr %#x.\n", hr);
854 IDirectDrawSurface4_Release(dst_surface);
855 IDirectDrawSurface4_Release(src_surface);
856 IDirectDrawClipper_Release(clipper);
857 IDirectDraw4_Release(ddraw);
860 static void test_coop_level_d3d_state(void)
862 D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
863 IDirectDrawSurface4 *rt, *surface;
864 IDirect3DViewport3 *viewport;
865 IDirect3DDevice3 *device;
873 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
874 0, 0, 640, 480, 0, 0, 0, 0);
875 if (!(device = create_device(window, DDSCL_NORMAL)))
877 skip("Failed to create D3D device, skipping test.\n");
878 DestroyWindow(window);
882 viewport = create_viewport(device, 0, 0, 640, 480);
884 hr = IDirect3DDevice3_GetRenderTarget(device, &rt);
885 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
886 hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_ZENABLE, &value);
887 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
888 ok(!!value, "Got unexpected z-enable state %#x.\n", value);
889 hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
890 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
891 ok(!value, "Got unexpected alpha blend enable state %#x.\n", value);
892 hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
893 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
894 hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
895 ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
896 color = get_surface_color(rt, 320, 240);
897 ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
899 hr = IDirect3DDevice3_GetDirect3D(device, &d3d);
900 ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
901 hr = IDirect3D3_QueryInterface(d3d, &IID_IDirectDraw4, (void **)&ddraw);
902 ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr);
903 IDirect3D3_Release(d3d);
904 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
905 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
906 hr = IDirectDrawSurface4_IsLost(rt);
907 ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
908 hr = IDirectDraw4_RestoreAllSurfaces(ddraw);
909 ok(SUCCEEDED(hr), "Failed to restore surfaces, hr %#x.\n", hr);
910 IDirectDraw4_Release(ddraw);
912 hr = IDirect3DDevice3_GetRenderTarget(device, &surface);
913 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
914 ok(surface == rt, "Got unexpected surface %p.\n", surface);
915 hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_ZENABLE, &value);
916 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
917 ok(!!value, "Got unexpected z-enable state %#x.\n", value);
918 hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
919 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
920 ok(!!value, "Got unexpected alpha blend enable state %#x.\n", value);
921 hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
922 ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
923 color = get_surface_color(rt, 320, 240);
924 ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
926 destroy_viewport(device, viewport);
927 IDirectDrawSurface4_Release(surface);
928 IDirectDrawSurface4_Release(rt);
929 IDirect3DDevice3_Release(device);
930 DestroyWindow(window);
933 static void test_surface_interface_mismatch(void)
935 IDirectDraw4 *ddraw = NULL;
936 IDirect3D3 *d3d = NULL;
937 IDirectDrawSurface4 *surface = NULL, *ds;
938 IDirectDrawSurface3 *surface3 = NULL;
939 IDirect3DDevice3 *device = NULL;
940 IDirect3DViewport3 *viewport = NULL;
941 DDSURFACEDESC2 surface_desc;
947 D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
949 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
950 0, 0, 640, 480, 0, 0, 0, 0);
952 if (!(ddraw = create_ddraw()))
954 skip("Failed to create a ddraw object, skipping test.\n");
958 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
959 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
961 memset(&surface_desc, 0, sizeof(surface_desc));
962 surface_desc.dwSize = sizeof(surface_desc);
963 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
964 surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
965 surface_desc.dwWidth = 640;
966 surface_desc.dwHeight = 480;
968 hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL);
969 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
971 hr = IDirectDrawSurface4_QueryInterface(surface, &IID_IDirectDrawSurface3, (void **)&surface3);
972 ok(SUCCEEDED(hr), "Failed to QI IDirectDrawSurface3, hr %#x.\n", hr);
974 hr = IDirectDraw4_QueryInterface(ddraw, &IID_IDirect3D3, (void **)&d3d);
977 skip("Failed to get the IDirect3D7 interface, skipping test.\n");
981 memset(&z_fmt, 0, sizeof(z_fmt));
982 hr = IDirect3D3_EnumZBufferFormats(d3d, &IID_IDirect3DHALDevice, enum_z_fmt, &z_fmt);
983 if (FAILED(hr) || !z_fmt.dwSize)
985 skip("No depth buffer formats available, skipping test.\n");
989 memset(&surface_desc, 0, sizeof(surface_desc));
990 surface_desc.dwSize = sizeof(surface_desc);
991 surface_desc.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT;
992 surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
993 U4(surface_desc).ddpfPixelFormat = z_fmt;
994 surface_desc.dwWidth = 640;
995 surface_desc.dwHeight = 480;
996 hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &ds, NULL);
997 ok(SUCCEEDED(hr), "Failed to create depth buffer, hr %#x.\n", hr);
1001 /* Using a different surface interface version still works */
1002 hr = IDirectDrawSurface3_AddAttachedSurface(surface3, (IDirectDrawSurface3 *)ds);
1003 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x.\n", hr);
1004 refcount = IDirectDrawSurface4_Release(ds);
1005 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
1010 hr = IDirect3D3_CreateDevice(d3d, &IID_IDirect3DHALDevice, (IDirectDrawSurface4 *)surface3, &device, NULL);
1011 ok(SUCCEEDED(hr), "Failed to create d3d device.\n");
1015 viewport = create_viewport(device, 0, 0, 640, 480);
1017 hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
1018 ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
1019 color = get_surface_color(surface, 320, 240);
1020 ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
1024 destroy_viewport(device, viewport);
1025 if (surface3) IDirectDrawSurface3_Release(surface3);
1026 if (surface) IDirectDrawSurface4_Release(surface);
1027 if (device) IDirect3DDevice3_Release(device);
1028 if (d3d) IDirect3D3_Release(d3d);
1029 if (ddraw) IDirectDraw4_Release(ddraw);
1030 DestroyWindow(window);
1033 static void test_coop_level_threaded(void)
1035 struct create_window_thread_param p;
1036 IDirectDraw4 *ddraw;
1039 if (!(ddraw = create_ddraw()))
1041 skip("Failed to create a ddraw object, skipping test.\n");
1044 create_window_thread(&p);
1046 hr = IDirectDraw4_SetCooperativeLevel(ddraw, p.window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1047 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
1049 IDirectDraw4_Release(ddraw);
1050 destroy_window_thread(&p);
1053 static void test_depth_blit(void)
1062 { -1.0, 1.0, 0.50f, 0xff00ff00},
1063 { 1.0, 1.0, 0.50f, 0xff00ff00},
1064 { -1.0, -1.0, 0.50f, 0xff00ff00},
1065 { 1.0, -1.0, 0.50f, 0xff00ff00},
1067 static const D3DCOLOR expected_colors[4][4] =
1069 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1070 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1071 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1072 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1074 DDSURFACEDESC2 ddsd_new, ddsd_existing;
1076 IDirect3DDevice3 *device;
1077 IDirectDrawSurface4 *ds1, *ds2, *ds3, *rt;
1078 IDirect3DViewport3 *viewport;
1079 RECT src_rect, dst_rect;
1084 IDirectDraw4 *ddraw;
1089 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1090 0, 0, 640, 480, 0, 0, 0, 0);
1091 if (!(device = create_device(window, DDSCL_NORMAL)))
1093 skip("Failed to create D3D device, skipping test.\n");
1094 DestroyWindow(window);
1098 hr = IDirect3DDevice3_GetDirect3D(device, &d3d);
1099 ok(SUCCEEDED(hr), "Failed to get Direct3D3 interface, hr %#x.\n", hr);
1100 hr = IDirect3D3_QueryInterface(d3d, &IID_IDirectDraw4, (void **)&ddraw);
1101 ok(SUCCEEDED(hr), "Failed to get DirectDraw4 interface, hr %#x.\n", hr);
1102 IDirect3D3_Release(d3d);
1104 ds1 = get_depth_stencil(device);
1106 memset(&ddsd_new, 0, sizeof(ddsd_new));
1107 ddsd_new.dwSize = sizeof(ddsd_new);
1108 memset(&ddsd_existing, 0, sizeof(ddsd_existing));
1109 ddsd_existing.dwSize = sizeof(ddsd_existing);
1110 hr = IDirectDrawSurface4_GetSurfaceDesc(ds1, &ddsd_existing);
1111 ddsd_new.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1112 ddsd_new.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
1113 ddsd_new.dwWidth = ddsd_existing.dwWidth;
1114 ddsd_new.dwHeight = ddsd_existing.dwHeight;
1115 U4(ddsd_new).ddpfPixelFormat = U4(ddsd_existing).ddpfPixelFormat;
1116 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd_new, &ds2, NULL);
1117 ok(SUCCEEDED(hr), "Failed to create a surface, hr %#x.\n", hr);
1118 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd_new, &ds3, NULL);
1119 ok(SUCCEEDED(hr), "Failed to create a surface, hr %#x.\n", hr);
1120 IDirectDraw4_Release(ddraw);
1122 viewport = create_viewport(device, 0, 0, ddsd_existing.dwWidth, ddsd_existing.dwHeight);
1123 hr = IDirect3DDevice3_SetCurrentViewport(device, viewport);
1124 ok(SUCCEEDED(hr), "Failed to activate the viewport, hr %#x.\n", hr);
1126 hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_TRUE);
1127 ok(SUCCEEDED(hr), "Failed to enable z testing, hr %#x.\n", hr);
1128 hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
1129 ok(SUCCEEDED(hr), "Failed to set the z function, hr %#x.\n", hr);
1130 hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
1131 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
1133 U1(d3drect).x1 = U2(d3drect).y1 = 0;
1134 U3(d3drect).x2 = ddsd_existing.dwWidth; U4(d3drect).y2 = ddsd_existing.dwHeight;
1135 hr = IDirect3DViewport3_Clear2(viewport, 1, &d3drect, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
1136 ok(SUCCEEDED(hr), "Failed to clear the z buffer, hr %#x.\n", hr);
1139 SetRect(&src_rect, 0, 0, 320, 240);
1140 SetRect(&dst_rect, 0, 0, 320, 240);
1141 hr = IDirectDrawSurface4_Blt(ds2, &dst_rect, ds1, &src_rect, DDBLT_WAIT, NULL);
1142 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1143 /* Different locations. */
1144 SetRect(&src_rect, 0, 0, 320, 240);
1145 SetRect(&dst_rect, 320, 240, 640, 480);
1146 hr = IDirectDrawSurface4_Blt(ds2, &dst_rect, ds1, &src_rect, DDBLT_WAIT, NULL);
1147 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1149 SetRect(&src_rect, 0, 0, 320, 240);
1150 SetRect(&dst_rect, 0, 0, 640, 480);
1151 hr = IDirectDrawSurface4_Blt(ds2, &dst_rect, ds1, &src_rect, DDBLT_WAIT, NULL);
1152 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1154 SetRect(&src_rect, 0, 480, 640, 0);
1155 SetRect(&dst_rect, 0, 0, 640, 480);
1156 hr = IDirectDrawSurface4_Blt(ds2, &dst_rect, ds1, &src_rect, DDBLT_WAIT, NULL);
1157 ok(hr == DDERR_INVALIDRECT, "Got unexpected hr %#x.\n", hr);
1158 SetRect(&src_rect, 0, 0, 640, 480);
1159 SetRect(&dst_rect, 0, 480, 640, 0);
1160 hr = IDirectDrawSurface4_Blt(ds2, &dst_rect, ds1, &src_rect, DDBLT_WAIT, NULL);
1161 ok(hr == DDERR_INVALIDRECT, "Got unexpected hr %#x.\n", hr);
1162 /* Full, explicit. */
1163 SetRect(&src_rect, 0, 0, 640, 480);
1164 SetRect(&dst_rect, 0, 0, 640, 480);
1165 hr = IDirectDrawSurface4_Blt(ds2, &dst_rect, ds1, &src_rect, DDBLT_WAIT, NULL);
1166 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1167 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1169 /* Depth blit inside a BeginScene / EndScene pair */
1170 hr = IDirect3DDevice3_BeginScene(device);
1171 ok(SUCCEEDED(hr), "Failed to start a scene, hr %#x.\n", hr);
1172 /* From the current depth stencil */
1173 hr = IDirectDrawSurface4_Blt(ds2, NULL, ds1, NULL, DDBLT_WAIT, NULL);
1174 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1175 /* To the current depth stencil */
1176 hr = IDirectDrawSurface4_Blt(ds1, NULL, ds2, NULL, DDBLT_WAIT, NULL);
1177 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1178 /* Between unbound surfaces */
1179 hr = IDirectDrawSurface4_Blt(ds3, NULL, ds2, NULL, DDBLT_WAIT, NULL);
1180 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1181 hr = IDirect3DDevice3_EndScene(device);
1182 ok(SUCCEEDED(hr), "Failed to end a scene, hr %#x.\n", hr);
1184 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1185 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1186 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1187 * a reliable result(z = 0.0) */
1188 memset(&fx, 0, sizeof(fx));
1189 fx.dwSize = sizeof(fx);
1190 hr = IDirectDrawSurface4_Blt(ds2, NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &fx);
1191 ok(SUCCEEDED(hr), "Failed to clear the source z buffer, hr %#x.\n", hr);
1193 hr = IDirect3DViewport3_Clear2(viewport, 1, &d3drect, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
1194 ok(SUCCEEDED(hr), "Failed to clear the color and z buffers, hr %#x.\n", hr);
1195 SetRect(&dst_rect, 0, 0, 320, 240);
1196 hr = IDirectDrawSurface4_Blt(ds1, &dst_rect, ds2, NULL, DDBLT_WAIT, NULL);
1197 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1198 IDirectDrawSurface4_Release(ds3);
1199 IDirectDrawSurface4_Release(ds2);
1200 IDirectDrawSurface4_Release(ds1);
1202 hr = IDirect3DDevice3_BeginScene(device);
1203 ok(SUCCEEDED(hr), "Failed to start a scene, hr %#x.\n", hr);
1204 hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE,
1206 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1207 hr = IDirect3DDevice3_EndScene(device);
1208 ok(SUCCEEDED(hr), "Failed to end a scene, hr %#x.\n", hr);
1210 hr = IDirect3DDevice3_GetRenderTarget(device, &rt);
1211 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
1212 for (i = 0; i < 4; ++i)
1214 for (j = 0; j < 4; ++j)
1216 unsigned int x = 80 * ((2 * j) + 1);
1217 unsigned int y = 60 * ((2 * i) + 1);
1218 color = get_surface_color(rt, x, y);
1219 ok(compare_color(color, expected_colors[i][j], 1),
1220 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
1223 IDirectDrawSurface4_Release(rt);
1225 destroy_viewport(device, viewport);
1226 IDirect3DDevice3_Release(device);
1227 DestroyWindow(window);
1230 static void test_texture_load_ckey(void)
1232 IDirectDraw4 *ddraw;
1233 IDirectDrawSurface4 *src;
1234 IDirectDrawSurface4 *dst;
1235 IDirect3DTexture2 *src_tex;
1236 IDirect3DTexture2 *dst_tex;
1237 DDSURFACEDESC2 ddsd;
1241 if (!(ddraw = create_ddraw()))
1243 skip("Failed to create ddraw object, skipping test.\n");
1246 hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
1247 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
1249 memset(&ddsd, 0, sizeof(ddsd));
1250 ddsd.dwSize = sizeof(ddsd);
1251 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
1252 ddsd.dwHeight = 128;
1254 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
1255 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &src, NULL);
1256 ok(SUCCEEDED(hr), "Failed to create source texture, hr %#x.\n", hr);
1257 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1258 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &dst, NULL);
1259 ok(SUCCEEDED(hr), "Failed to create destination texture, hr %#x.\n", hr);
1261 hr = IDirectDrawSurface4_QueryInterface(src, &IID_IDirect3DTexture2, (void **)&src_tex);
1262 ok(SUCCEEDED(hr) || hr == E_NOINTERFACE, "Failed to get Direct3DTexture2 interface, hr %#x.\n", hr);
1265 /* 64 bit ddraw does not support d3d */
1266 skip("Could not get Direct3DTexture2 interface, skipping texture::Load color keying tests.\n");
1267 IDirectDrawSurface4_Release(dst);
1268 IDirectDrawSurface4_Release(src);
1269 IDirectDraw4_Release(ddraw);
1272 hr = IDirectDrawSurface4_QueryInterface(dst, &IID_IDirect3DTexture2, (void **)&dst_tex);
1273 ok(SUCCEEDED(hr), "Failed to get Direct3DTexture2 interface, hr %#x.\n", hr);
1275 /* No surface has a color key */
1276 hr = IDirect3DTexture2_Load(dst_tex, src_tex);
1277 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1278 ckey.dwColorSpaceLowValue = ckey.dwColorSpaceHighValue = 0xdeadbeef;
1279 hr = IDirectDrawSurface4_GetColorKey(dst, DDCKEY_SRCBLT, &ckey);
1280 ok(hr == DDERR_NOCOLORKEY, "Got unexpected hr %#x.\n", hr);
1281 ok(ckey.dwColorSpaceLowValue == 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey.dwColorSpaceLowValue);
1282 ok(ckey.dwColorSpaceHighValue == 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey.dwColorSpaceHighValue);
1284 /* Source surface has a color key */
1285 ckey.dwColorSpaceLowValue = ckey.dwColorSpaceHighValue = 0x0000ff00;
1286 hr = IDirectDrawSurface4_SetColorKey(src, DDCKEY_SRCBLT, &ckey);
1287 ok(SUCCEEDED(hr), "Failed to set color key, hr %#x.\n", hr);
1288 hr = IDirect3DTexture2_Load(dst_tex, src_tex);
1289 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1290 hr = IDirectDrawSurface4_GetColorKey(dst, DDCKEY_SRCBLT, &ckey);
1291 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1292 ok(ckey.dwColorSpaceLowValue == 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey.dwColorSpaceLowValue);
1293 ok(ckey.dwColorSpaceHighValue == 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey.dwColorSpaceHighValue);
1295 /* Both surfaces have a color key: Dest ckey is overwritten */
1296 ckey.dwColorSpaceLowValue = ckey.dwColorSpaceHighValue = 0x000000ff;
1297 hr = IDirectDrawSurface4_SetColorKey(dst, DDCKEY_SRCBLT, &ckey);
1298 ok(SUCCEEDED(hr), "Failed to set color key, hr %#x.\n", hr);
1299 hr = IDirect3DTexture2_Load(dst_tex, src_tex);
1300 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1301 hr = IDirectDrawSurface4_GetColorKey(dst, DDCKEY_SRCBLT, &ckey);
1302 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1303 ok(ckey.dwColorSpaceLowValue == 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey.dwColorSpaceLowValue);
1304 ok(ckey.dwColorSpaceHighValue == 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey.dwColorSpaceHighValue);
1306 /* Only the destination has a color key: It is not deleted */
1307 hr = IDirectDrawSurface4_SetColorKey(src, DDCKEY_SRCBLT, NULL);
1308 ok(SUCCEEDED(hr), "Failed to set color key, hr %#x.\n", hr);
1309 hr = IDirectDrawSurface4_GetColorKey(src, DDCKEY_SRCBLT, &ckey);
1310 ok(hr == DDERR_NOCOLORKEY, "Got unexpected hr %#x.\n", hr);
1311 hr = IDirect3DTexture2_Load(dst_tex, src_tex);
1312 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1313 hr = IDirectDrawSurface4_GetColorKey(dst, DDCKEY_SRCBLT, &ckey);
1314 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1315 ok(ckey.dwColorSpaceLowValue == 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey.dwColorSpaceLowValue);
1316 ok(ckey.dwColorSpaceHighValue == 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey.dwColorSpaceHighValue);
1318 IDirect3DTexture2_Release(dst_tex);
1319 IDirect3DTexture2_Release(src_tex);
1320 IDirectDrawSurface4_Release(dst);
1321 IDirectDrawSurface4_Release(src);
1322 IDirectDraw4_Release(ddraw);
1325 static ULONG get_refcount(IUnknown *test_iface)
1327 IUnknown_AddRef(test_iface);
1328 return IUnknown_Release(test_iface);
1331 static void test_viewport_interfaces(void)
1333 IDirectDraw4 *ddraw;
1335 HRESULT hr, old_d3d_ref;
1337 IDirect3DViewport *viewport;
1338 IDirect3DViewport2 *viewport2;
1339 IDirect3DViewport3 *viewport3;
1340 IDirectDrawGammaControl *gamma;
1343 if (!(ddraw = create_ddraw()))
1345 skip("Failed to create ddraw object, skipping test.\n");
1348 hr = IDirectDraw4_QueryInterface(ddraw, &IID_IDirect3D3, (void **)&d3d);
1349 ok(SUCCEEDED(hr) || hr == E_NOINTERFACE, "Failed to get d3d interface, hr %#x.\n", hr);
1352 skip("Direct3D not available, skipping tests\n");
1353 IDirectDraw4_Release(ddraw);
1356 old_d3d_ref = get_refcount((IUnknown *)d3d);
1358 hr = IDirect3D3_CreateViewport(d3d, &viewport3, NULL);
1359 ok(SUCCEEDED(hr), "Failed to create viewport, hr %#x.\n", hr);
1360 ref = get_refcount((IUnknown *)viewport3);
1361 ok(ref == 1, "Initial IDirect3DViewport3 refcount is %u\n", ref);
1362 ref = get_refcount((IUnknown *)d3d);
1363 ok(ref == old_d3d_ref, "IDirect3D3 refcount is %u\n", ref);
1365 gamma = (IDirectDrawGammaControl *)0xdeadbeef;
1366 hr = IDirect3DViewport2_QueryInterface(viewport3, &IID_IDirectDrawGammaControl, (void **)&gamma);
1367 ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
1368 ok(gamma == NULL, "Interface not set to NULL by failed QI call: %p\n", gamma);
1369 if (SUCCEEDED(hr)) IDirectDrawGammaControl_Release(gamma);
1370 /* NULL iid: Segfaults */
1372 hr = IDirect3DViewport3_QueryInterface(viewport3, &IID_IDirect3DViewport, (void **)&viewport);
1373 ok(SUCCEEDED(hr), "Failed to QI IDirect3DViewport, hr %#x.\n", hr);
1376 ref = get_refcount((IUnknown *)viewport);
1377 ok(ref == 2, "IDirect3DViewport refcount is %u\n", ref);
1378 ref = get_refcount((IUnknown *)viewport3);
1379 ok(ref == 2, "IDirect3DViewport3 refcount is %u\n", ref);
1380 IDirect3DViewport_Release(viewport);
1384 hr = IDirect3DViewport3_QueryInterface(viewport3, &IID_IDirect3DViewport3, (void **)&viewport2);
1385 ok(SUCCEEDED(hr), "Failed to QI IDirect3DViewport3, hr %#x.\n", hr);
1388 ref = get_refcount((IUnknown *)viewport2);
1389 ok(ref == 2, "IDirect3DViewport2 refcount is %u\n", ref);
1390 ref = get_refcount((IUnknown *)viewport3);
1391 ok(ref == 2, "IDirect3DViewport3 refcount is %u\n", ref);
1392 IDirect3DViewport3_Release(viewport2);
1395 hr = IDirect3DViewport3_QueryInterface(viewport3, &IID_IUnknown, (void **)&unknown);
1396 ok(SUCCEEDED(hr), "Failed to QI IUnknown, hr %#x.\n", hr);
1399 ref = get_refcount((IUnknown *)viewport3);
1400 ok(ref == 2, "IDirect3DViewport3 refcount is %u\n", ref);
1401 ref = get_refcount(unknown);
1402 ok(ref == 2, "IUnknown refcount is %u\n", ref);
1403 IUnknown_Release(unknown);
1406 IDirect3DViewport3_Release(viewport3);
1407 IDirect3D3_Release(d3d);
1408 IDirectDraw4_Release(ddraw);
1411 static void test_zenable(void)
1413 static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
1416 struct vec4 position;
1421 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
1422 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
1423 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
1424 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
1426 IDirect3DViewport3 *viewport;
1427 IDirect3DDevice3 *device;
1428 IDirectDrawSurface4 *rt;
1435 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1436 0, 0, 640, 480, 0, 0, 0, 0);
1437 if (!(device = create_device(window, DDSCL_NORMAL)))
1439 skip("Failed to create D3D device, skipping test.\n");
1440 DestroyWindow(window);
1444 viewport = create_viewport(device, 0, 0, 640, 480);
1445 hr = IDirect3DDevice3_SetCurrentViewport(device, viewport);
1446 ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
1448 hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_FALSE);
1449 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
1451 hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
1452 ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
1453 hr = IDirect3DDevice3_BeginScene(device);
1454 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1455 hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, tquad, 4, 0);
1456 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1457 hr = IDirect3DDevice3_EndScene(device);
1458 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1460 hr = IDirect3DDevice3_GetRenderTarget(device, &rt);
1461 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
1462 for (i = 0; i < 4; ++i)
1464 for (j = 0; j < 4; ++j)
1466 x = 80 * ((2 * j) + 1);
1467 y = 60 * ((2 * i) + 1);
1468 color = get_surface_color(rt, x, y);
1469 ok(compare_color(color, 0x0000ff00, 1),
1470 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
1473 IDirectDrawSurface4_Release(rt);
1475 destroy_viewport(device, viewport);
1476 IDirect3DDevice3_Release(device);
1477 DestroyWindow(window);
1480 static void test_ck_rgba(void)
1482 static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
1485 struct vec4 position;
1486 struct vec2 texcoord;
1490 {{ 0.0f, 480.0f, 0.25f, 1.0f}, {0.0f, 0.0f}},
1491 {{ 0.0f, 0.0f, 0.25f, 1.0f}, {0.0f, 1.0f}},
1492 {{640.0f, 480.0f, 0.25f, 1.0f}, {1.0f, 0.0f}},
1493 {{640.0f, 0.0f, 0.25f, 1.0f}, {1.0f, 1.0f}},
1494 {{ 0.0f, 480.0f, 0.75f, 1.0f}, {0.0f, 0.0f}},
1495 {{ 0.0f, 0.0f, 0.75f, 1.0f}, {0.0f, 1.0f}},
1496 {{640.0f, 480.0f, 0.75f, 1.0f}, {1.0f, 0.0f}},
1497 {{640.0f, 0.0f, 0.75f, 1.0f}, {1.0f, 1.0f}},
1501 D3DCOLOR fill_color;
1509 {0xff00ff00, TRUE, TRUE, 0x00ff0000, 0x000000ff},
1510 {0xff00ff00, TRUE, FALSE, 0x00ff0000, 0x000000ff},
1511 {0xff00ff00, FALSE, TRUE, 0x0000ff00, 0x0000ff00},
1512 {0xff00ff00, FALSE, FALSE, 0x0000ff00, 0x0000ff00},
1513 {0x7f00ff00, TRUE, TRUE, 0x00807f00, 0x00807f00},
1514 {0x7f00ff00, TRUE, FALSE, 0x0000ff00, 0x0000ff00},
1515 {0x7f00ff00, FALSE, TRUE, 0x00807f00, 0x00807f00},
1516 {0x7f00ff00, FALSE, FALSE, 0x0000ff00, 0x0000ff00},
1519 IDirectDrawSurface4 *surface;
1520 IDirect3DViewport3 *viewport;
1521 DDSURFACEDESC2 surface_desc;
1522 IDirect3DTexture2 *texture;
1523 IDirect3DDevice3 *device;
1524 IDirectDrawSurface4 *rt;
1525 IDirectDraw4 *ddraw;
1533 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1534 0, 0, 640, 480, 0, 0, 0, 0);
1535 if (!(device = create_device(window, DDSCL_NORMAL)))
1537 skip("Failed to create D3D device, skipping test.\n");
1538 DestroyWindow(window);
1542 viewport = create_viewport(device, 0, 0, 640, 480);
1543 hr = IDirect3DDevice3_SetCurrentViewport(device, viewport);
1544 ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
1546 hr = IDirect3DDevice3_GetDirect3D(device, &d3d);
1547 ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
1548 hr = IDirect3D3_QueryInterface(d3d, &IID_IDirectDraw4, (void **)&ddraw);
1549 ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr);
1550 IDirect3D3_Release(d3d);
1552 memset(&surface_desc, 0, sizeof(surface_desc));
1553 surface_desc.dwSize = sizeof(surface_desc);
1554 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT;
1555 surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1556 surface_desc.dwWidth = 256;
1557 surface_desc.dwHeight = 256;
1558 U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
1559 U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1560 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32;
1561 U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1562 U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1563 U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff;
1564 U5(U4(surface_desc).ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
1565 surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue = 0xff00ff00;
1566 surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue = 0xff00ff00;
1567 hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL);
1568 ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr);
1569 hr = IDirectDrawSurface4_QueryInterface(surface, &IID_IDirect3DTexture2, (void **)&texture);
1570 ok(SUCCEEDED(hr), "Failed to get texture interface, hr %#x.\n", hr);
1572 hr = IDirect3DDevice3_SetTexture(device, 0, texture);
1573 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
1574 hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
1575 ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
1576 hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
1577 ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
1579 hr = IDirect3DDevice3_GetRenderTarget(device, &rt);
1580 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
1582 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
1584 hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, tests[i].color_key);
1585 ok(SUCCEEDED(hr), "Failed to enable color keying, hr %#x.\n", hr);
1586 hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, tests[i].blend);
1587 ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
1589 memset(&fx, 0, sizeof(fx));
1590 fx.dwSize = sizeof(fx);
1591 U5(fx).dwFillColor = tests[i].fill_color;
1592 hr = IDirectDrawSurface4_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
1593 ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr);
1595 hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect,
1596 D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
1597 ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
1598 hr = IDirect3DDevice3_BeginScene(device);
1599 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1600 hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[0], 4, 0);
1601 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1602 hr = IDirect3DDevice3_EndScene(device);
1603 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1605 color = get_surface_color(rt, 320, 240);
1607 todo_wine ok(compare_color(color, tests[i].result1, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1608 tests[i].result1, i, color);
1610 ok(compare_color(color, tests[i].result1, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1611 tests[i].result1, i, color);
1613 U5(fx).dwFillColor = 0xff0000ff;
1614 hr = IDirectDrawSurface4_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
1615 ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr);
1617 hr = IDirect3DDevice3_BeginScene(device);
1618 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1619 hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[4], 4, 0);
1620 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1621 hr = IDirect3DDevice3_EndScene(device);
1622 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1624 /* This tests that fragments that are masked out by the color key are
1625 * discarded, instead of just fully transparent. */
1626 color = get_surface_color(rt, 320, 240);
1628 todo_wine ok(compare_color(color, tests[i].result2, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1629 tests[i].result2, i, color);
1631 ok(compare_color(color, tests[i].result2, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1632 tests[i].result2, i, color);
1635 IDirectDrawSurface4_Release(rt);
1636 IDirect3DTexture2_Release(texture);
1637 IDirectDrawSurface4_Release(surface);
1638 destroy_viewport(device, viewport);
1639 IDirectDraw4_Release(ddraw);
1640 IDirect3DDevice3_Release(device);
1641 DestroyWindow(window);
1644 static void test_ck_default(void)
1646 static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
1649 struct vec4 position;
1650 struct vec2 texcoord;
1654 {{ 0.0f, 480.0f, 0.0f, 1.0f}, {0.0f, 0.0f}},
1655 {{ 0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}},
1656 {{640.0f, 480.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
1657 {{640.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
1659 IDirectDrawSurface4 *surface, *rt;
1660 IDirect3DViewport3 *viewport;
1661 DDSURFACEDESC2 surface_desc;
1662 IDirect3DTexture2 *texture;
1663 IDirect3DDevice3 *device;
1664 IDirectDraw4 *ddraw;
1672 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1673 0, 0, 640, 480, 0, 0, 0, 0);
1675 if (!(device = create_device(window, DDSCL_NORMAL)))
1677 skip("Failed to create D3D device, skipping test.\n");
1678 DestroyWindow(window);
1682 hr = IDirect3DDevice3_GetDirect3D(device, &d3d);
1683 ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
1684 hr = IDirect3D3_QueryInterface(d3d, &IID_IDirectDraw4, (void **)&ddraw);
1685 ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr);
1686 IDirect3D3_Release(d3d);
1688 hr = IDirect3DDevice3_GetRenderTarget(device, &rt);
1689 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
1691 viewport = create_viewport(device, 0, 0, 640, 480);
1692 hr = IDirect3DDevice3_SetCurrentViewport(device, viewport);
1693 ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
1695 memset(&surface_desc, 0, sizeof(surface_desc));
1696 surface_desc.dwSize = sizeof(surface_desc);
1697 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT;
1698 surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1699 surface_desc.dwWidth = 256;
1700 surface_desc.dwHeight = 256;
1701 U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
1702 U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB;
1703 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32;
1704 U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1705 U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1706 U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff;
1707 surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue = 0x000000ff;
1708 surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue = 0x000000ff;
1709 hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL);
1710 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1711 hr = IDirectDrawSurface4_QueryInterface(surface, &IID_IDirect3DTexture2, (void **)&texture);
1712 ok(SUCCEEDED(hr), "Failed to get texture interface, hr %#x.\n", hr);
1713 hr = IDirect3DDevice3_SetTexture(device, 0, texture);
1714 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
1716 memset(&fx, 0, sizeof(fx));
1717 fx.dwSize = sizeof(fx);
1718 U5(fx).dwFillColor = 0x000000ff;
1719 hr = IDirectDrawSurface4_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
1720 ok(SUCCEEDED(hr), "Failed to fill surface, hr %#x.\n", hr);
1722 hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0xff00ff00, 1.0f, 0);
1723 ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
1724 hr = IDirect3DDevice3_BeginScene(device);
1725 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1726 hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, &value);
1727 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1728 ok(!value, "Got unexpected color keying state %#x.\n", value);
1729 hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[0], 4, 0);
1730 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1731 hr = IDirect3DDevice3_EndScene(device);
1732 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1733 color = get_surface_color(rt, 320, 240);
1734 ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
1736 hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0xff00ff00, 1.0f, 0);
1737 ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
1738 hr = IDirect3DDevice3_BeginScene(device);
1739 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1740 hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, TRUE);
1741 ok(SUCCEEDED(hr), "Failed to enable color keying, hr %#x.\n", hr);
1742 hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[0], 4, 0);
1743 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1744 hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, &value);
1745 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1746 ok(!!value, "Got unexpected color keying state %#x.\n", value);
1747 hr = IDirect3DDevice3_EndScene(device);
1748 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1749 color = get_surface_color(rt, 320, 240);
1750 ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
1752 IDirect3DTexture_Release(texture);
1753 IDirectDrawSurface4_Release(surface);
1754 destroy_viewport(device, viewport);
1755 IDirectDrawSurface4_Release(rt);
1756 IDirect3DDevice3_Release(device);
1757 IDirectDraw4_Release(ddraw);
1758 DestroyWindow(window);
1764 REFIID refcount_iid;
1768 static void test_qi(const char *test_name, IUnknown *base_iface,
1769 REFIID refcount_iid, const struct qi_test *tests, UINT entry_count)
1771 ULONG refcount, expected_refcount;
1772 IUnknown *iface1, *iface2;
1776 for (i = 0; i < entry_count; ++i)
1778 hr = IUnknown_QueryInterface(base_iface, tests[i].iid, (void **)&iface1);
1779 ok(hr == tests[i].hr, "Got hr %#x for test \"%s\" %u.\n", hr, test_name, i);
1782 for (j = 0; j < entry_count; ++j)
1784 hr = IUnknown_QueryInterface(iface1, tests[j].iid, (void **)&iface2);
1785 ok(hr == tests[j].hr, "Got hr %#x for test \"%s\" %u, %u.\n", hr, test_name, i, j);
1788 expected_refcount = 0;
1789 if (IsEqualGUID(refcount_iid, tests[j].refcount_iid))
1790 ++expected_refcount;
1791 if (IsEqualGUID(tests[i].refcount_iid, tests[j].refcount_iid))
1792 ++expected_refcount;
1793 refcount = IUnknown_Release(iface2);
1794 ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
1795 refcount, test_name, i, j, expected_refcount);
1799 expected_refcount = 0;
1800 if (IsEqualGUID(refcount_iid, tests[i].refcount_iid))
1801 ++expected_refcount;
1802 refcount = IUnknown_Release(iface1);
1803 ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, expected %u.\n",
1804 refcount, test_name, i, expected_refcount);
1809 static void test_surface_qi(void)
1811 static const struct qi_test tests[] =
1813 {&IID_IDirect3DTexture2, &IID_IDirectDrawSurface4, S_OK },
1814 {&IID_IDirect3DTexture, &IID_IDirectDrawSurface4, S_OK },
1815 {&IID_IDirectDrawGammaControl, &IID_IDirectDrawGammaControl, S_OK },
1816 {&IID_IDirectDrawColorControl, NULL, E_NOINTERFACE},
1817 {&IID_IDirectDrawSurface7, &IID_IDirectDrawSurface7, S_OK },
1818 {&IID_IDirectDrawSurface4, &IID_IDirectDrawSurface4, S_OK },
1819 {&IID_IDirectDrawSurface3, &IID_IDirectDrawSurface3, S_OK },
1820 {&IID_IDirectDrawSurface2, &IID_IDirectDrawSurface2, S_OK },
1821 {&IID_IDirectDrawSurface, &IID_IDirectDrawSurface, S_OK },
1822 {&IID_IDirect3DDevice7, NULL, E_INVALIDARG },
1823 {&IID_IDirect3DDevice3, NULL, E_INVALIDARG },
1824 {&IID_IDirect3DDevice2, NULL, E_INVALIDARG },
1825 {&IID_IDirect3DDevice, NULL, E_INVALIDARG },
1826 {&IID_IDirect3D7, NULL, E_INVALIDARG },
1827 {&IID_IDirect3D3, NULL, E_INVALIDARG },
1828 {&IID_IDirect3D2, NULL, E_INVALIDARG },
1829 {&IID_IDirect3D, NULL, E_INVALIDARG },
1830 {&IID_IDirectDraw7, NULL, E_INVALIDARG },
1831 {&IID_IDirectDraw4, NULL, E_INVALIDARG },
1832 {&IID_IDirectDraw3, NULL, E_INVALIDARG },
1833 {&IID_IDirectDraw2, NULL, E_INVALIDARG },
1834 {&IID_IDirectDraw, NULL, E_INVALIDARG },
1835 {&IID_IDirect3DLight, NULL, E_INVALIDARG },
1836 {&IID_IDirect3DMaterial, NULL, E_INVALIDARG },
1837 {&IID_IDirect3DMaterial2, NULL, E_INVALIDARG },
1838 {&IID_IDirect3DMaterial3, NULL, E_INVALIDARG },
1839 {&IID_IDirect3DExecuteBuffer, NULL, E_INVALIDARG },
1840 {&IID_IDirect3DViewport, NULL, E_INVALIDARG },
1841 {&IID_IDirect3DViewport2, NULL, E_INVALIDARG },
1842 {&IID_IDirect3DViewport3, NULL, E_INVALIDARG },
1843 {&IID_IDirect3DVertexBuffer, NULL, E_INVALIDARG },
1844 {&IID_IDirect3DVertexBuffer7, NULL, E_INVALIDARG },
1845 {&IID_IDirectDrawPalette, NULL, E_INVALIDARG },
1846 {&IID_IDirectDrawClipper, NULL, E_INVALIDARG },
1847 {&IID_IUnknown, &IID_IDirectDrawSurface, S_OK },
1850 IDirectDrawSurface4 *surface;
1851 DDSURFACEDESC2 surface_desc;
1852 IDirect3DDevice3 *device;
1853 IDirectDraw4 *ddraw;
1857 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
1859 win_skip("DirectDrawCreateEx not available, skipping test.\n");
1863 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1864 0, 0, 640, 480, 0, 0, 0, 0);
1865 /* Try to create a D3D device to see if the ddraw implementation supports
1866 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
1867 * doesn't support e.g. the IDirect3DTexture interfaces. */
1868 if (!(device = create_device(window, DDSCL_NORMAL)))
1870 skip("Failed to create D3D device, skipping test.\n");
1871 DestroyWindow(window);
1874 IDirect3DDevice_Release(device);
1875 if (!(ddraw = create_ddraw()))
1877 skip("Failed to create a ddraw object, skipping test.\n");
1878 DestroyWindow(window);
1881 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
1882 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
1884 memset(&surface_desc, 0, sizeof(surface_desc));
1885 surface_desc.dwSize = sizeof(surface_desc);
1886 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1887 surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1888 surface_desc.dwWidth = 512;
1889 surface_desc.dwHeight = 512;
1890 hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL);
1891 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1893 test_qi("surface_qi", (IUnknown *)surface, &IID_IDirectDrawSurface4, tests, sizeof(tests) / sizeof(*tests));
1895 IDirectDrawSurface4_Release(surface);
1896 IDirectDraw4_Release(ddraw);
1897 DestroyWindow(window);
1900 static void test_device_qi(void)
1902 static const struct qi_test tests[] =
1904 {&IID_IDirect3DTexture2, NULL, E_NOINTERFACE},
1905 {&IID_IDirect3DTexture, NULL, E_NOINTERFACE},
1906 {&IID_IDirectDrawGammaControl, NULL, E_NOINTERFACE},
1907 {&IID_IDirectDrawColorControl, NULL, E_NOINTERFACE},
1908 {&IID_IDirectDrawSurface7, NULL, E_NOINTERFACE},
1909 {&IID_IDirectDrawSurface4, NULL, E_NOINTERFACE},
1910 {&IID_IDirectDrawSurface3, NULL, E_NOINTERFACE},
1911 {&IID_IDirectDrawSurface2, NULL, E_NOINTERFACE},
1912 {&IID_IDirectDrawSurface, NULL, E_NOINTERFACE},
1913 {&IID_IDirect3DDevice7, NULL, E_NOINTERFACE},
1914 {&IID_IDirect3DDevice3, &IID_IDirect3DDevice3, S_OK },
1915 {&IID_IDirect3DDevice2, &IID_IDirect3DDevice3, S_OK },
1916 {&IID_IDirect3DDevice, &IID_IDirect3DDevice3, S_OK },
1917 {&IID_IDirect3DRampDevice, NULL, E_NOINTERFACE},
1918 {&IID_IDirect3DRGBDevice, NULL, E_NOINTERFACE},
1919 {&IID_IDirect3DHALDevice, NULL, E_NOINTERFACE},
1920 {&IID_IDirect3DMMXDevice, NULL, E_NOINTERFACE},
1921 {&IID_IDirect3DRefDevice, NULL, E_NOINTERFACE},
1922 {&IID_IDirect3DTnLHalDevice, NULL, E_NOINTERFACE},
1923 {&IID_IDirect3DNullDevice, NULL, E_NOINTERFACE},
1924 {&IID_IDirect3D7, NULL, E_NOINTERFACE},
1925 {&IID_IDirect3D3, NULL, E_NOINTERFACE},
1926 {&IID_IDirect3D2, NULL, E_NOINTERFACE},
1927 {&IID_IDirect3D, NULL, E_NOINTERFACE},
1928 {&IID_IDirectDraw7, NULL, E_NOINTERFACE},
1929 {&IID_IDirectDraw4, NULL, E_NOINTERFACE},
1930 {&IID_IDirectDraw3, NULL, E_NOINTERFACE},
1931 {&IID_IDirectDraw2, NULL, E_NOINTERFACE},
1932 {&IID_IDirectDraw, NULL, E_NOINTERFACE},
1933 {&IID_IDirect3DLight, NULL, E_NOINTERFACE},
1934 {&IID_IDirect3DMaterial, NULL, E_NOINTERFACE},
1935 {&IID_IDirect3DMaterial2, NULL, E_NOINTERFACE},
1936 {&IID_IDirect3DMaterial3, NULL, E_NOINTERFACE},
1937 {&IID_IDirect3DExecuteBuffer, NULL, E_NOINTERFACE},
1938 {&IID_IDirect3DViewport, NULL, E_NOINTERFACE},
1939 {&IID_IDirect3DViewport2, NULL, E_NOINTERFACE},
1940 {&IID_IDirect3DViewport3, NULL, E_NOINTERFACE},
1941 {&IID_IDirect3DVertexBuffer, NULL, E_NOINTERFACE},
1942 {&IID_IDirect3DVertexBuffer7, NULL, E_NOINTERFACE},
1943 {&IID_IDirectDrawPalette, NULL, E_NOINTERFACE},
1944 {&IID_IDirectDrawClipper, NULL, E_NOINTERFACE},
1945 {&IID_IUnknown, &IID_IDirect3DDevice3, S_OK },
1948 IDirect3DDevice3 *device;
1951 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1952 0, 0, 640, 480, 0, 0, 0, 0);
1953 if (!(device = create_device(window, DDSCL_NORMAL)))
1955 skip("Failed to create D3D device, skipping test.\n");
1956 DestroyWindow(window);
1960 test_qi("device_qi", (IUnknown *)device, &IID_IDirect3DDevice3, tests, sizeof(tests) / sizeof(*tests));
1962 IDirect3DDevice3_Release(device);
1963 DestroyWindow(window);
1966 static void test_wndproc(void)
1968 LONG_PTR proc, ddraw_proc;
1969 IDirectDraw4 *ddraw;
1975 static const UINT messages[] =
1977 WM_WINDOWPOSCHANGING,
1980 WM_WINDOWPOSCHANGING,
1986 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
1987 if (!(ddraw = create_ddraw()))
1989 skip("Failed to create IDirectDraw4 object, skipping tests.\n");
1993 wc.lpfnWndProc = test_proc;
1994 wc.lpszClassName = "ddraw_test_wndproc_wc";
1995 ok(RegisterClassA(&wc), "Failed to register window class.\n");
1997 window = CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
1998 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
2000 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
2001 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2002 (LONG_PTR)test_proc, proc);
2003 expect_messages = messages;
2004 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2005 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2006 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
2007 expect_messages = NULL;
2008 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
2009 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2010 (LONG_PTR)test_proc, proc);
2011 ref = IDirectDraw4_Release(ddraw);
2012 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2013 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
2014 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2015 (LONG_PTR)test_proc, proc);
2017 /* DDSCL_NORMAL doesn't. */
2018 ddraw = create_ddraw();
2019 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
2020 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2021 (LONG_PTR)test_proc, proc);
2022 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
2023 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2024 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
2025 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2026 (LONG_PTR)test_proc, proc);
2027 ref = IDirectDraw4_Release(ddraw);
2028 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2029 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
2030 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2031 (LONG_PTR)test_proc, proc);
2033 /* The original window proc is only restored by ddraw if the current
2034 * window proc matches the one ddraw set. This also affects switching
2035 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2036 ddraw = create_ddraw();
2037 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
2038 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2039 (LONG_PTR)test_proc, proc);
2040 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2041 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2042 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
2043 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2044 (LONG_PTR)test_proc, proc);
2046 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
2047 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2048 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
2049 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2050 (LONG_PTR)test_proc, proc);
2051 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2052 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2053 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
2054 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2055 (LONG_PTR)test_proc, proc);
2056 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
2057 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2058 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
2059 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
2060 (LONG_PTR)DefWindowProcA, proc);
2061 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2062 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2063 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
2064 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
2065 (LONG_PTR)DefWindowProcA, proc);
2066 ref = IDirectDraw4_Release(ddraw);
2067 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2068 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
2069 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2070 (LONG_PTR)test_proc, proc);
2072 ddraw = create_ddraw();
2073 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
2074 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
2075 (LONG_PTR)test_proc, proc);
2076 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2077 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2078 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
2079 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
2080 (LONG_PTR)test_proc, proc);
2081 ref = IDirectDraw4_Release(ddraw);
2082 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2083 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
2084 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
2085 (LONG_PTR)DefWindowProcA, proc);
2087 fix_wndproc(window, (LONG_PTR)test_proc);
2088 expect_messages = NULL;
2089 DestroyWindow(window);
2090 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL));
2093 static void test_window_style(void)
2095 LONG style, exstyle, tmp;
2096 RECT fullscreen_rect, r;
2097 IDirectDraw4 *ddraw;
2102 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
2103 0, 0, 100, 100, 0, 0, 0, 0);
2104 if (!(ddraw = create_ddraw()))
2106 skip("Failed to create a ddraw object, skipping test.\n");
2107 DestroyWindow(window);
2111 style = GetWindowLongA(window, GWL_STYLE);
2112 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
2113 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2115 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2116 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2118 tmp = GetWindowLongA(window, GWL_STYLE);
2119 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
2120 tmp = GetWindowLongA(window, GWL_EXSTYLE);
2121 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
2123 GetWindowRect(window, &r);
2124 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2125 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2126 r.left, r.top, r.right, r.bottom);
2127 GetClientRect(window, &r);
2128 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
2130 ref = IDirectDraw4_Release(ddraw);
2131 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2133 DestroyWindow(window);
2136 static void test_redundant_mode_set(void)
2138 DDSURFACEDESC2 surface_desc = {0};
2139 IDirectDraw4 *ddraw;
2145 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
2146 0, 0, 100, 100, 0, 0, 0, 0);
2147 if (!(ddraw = create_ddraw()))
2149 skip("Failed to create a ddraw object, skipping test.\n");
2150 DestroyWindow(window);
2154 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2155 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2157 surface_desc.dwSize = sizeof(surface_desc);
2158 hr = IDirectDraw4_GetDisplayMode(ddraw, &surface_desc);
2159 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
2161 hr = IDirectDraw4_SetDisplayMode(ddraw, surface_desc.dwWidth, surface_desc.dwHeight,
2162 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
2163 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2165 GetWindowRect(window, &r);
2168 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
2169 GetWindowRect(window, &s);
2170 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2171 r.left, r.top, r.right, r.bottom,
2172 s.left, s.top, s.right, s.bottom);
2174 hr = IDirectDraw4_SetDisplayMode(ddraw, surface_desc.dwWidth, surface_desc.dwHeight,
2175 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
2176 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2178 GetWindowRect(window, &s);
2179 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2180 r.left, r.top, r.right, r.bottom,
2181 s.left, s.top, s.right, s.bottom);
2183 ref = IDirectDraw4_Release(ddraw);
2184 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2186 DestroyWindow(window);
2189 static SIZE screen_size;
2191 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
2193 if (message == WM_SIZE)
2195 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
2196 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
2199 return test_proc(hwnd, message, wparam, lparam);
2202 static void test_coop_level_mode_set(void)
2204 IDirectDrawSurface4 *primary;
2205 RECT fullscreen_rect, r, s;
2206 IDirectDraw4 *ddraw;
2207 DDSURFACEDESC2 ddsd;
2213 static const UINT exclusive_messages[] =
2215 WM_WINDOWPOSCHANGING,
2216 WM_WINDOWPOSCHANGED,
2222 static const UINT normal_messages[] =
2228 if (!(ddraw = create_ddraw()))
2230 skip("Failed to create a ddraw object, skipping test.\n");
2234 wc.lpfnWndProc = mode_set_proc;
2235 wc.lpszClassName = "ddraw_test_wndproc_wc";
2236 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2238 window = CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW,
2239 0, 0, 100, 100, 0, 0, 0, 0);
2241 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2242 SetRect(&s, 0, 0, 640, 480);
2244 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2245 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2247 GetWindowRect(window, &r);
2248 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2249 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2250 r.left, r.top, r.right, r.bottom);
2252 memset(&ddsd, 0, sizeof(ddsd));
2253 ddsd.dwSize = sizeof(ddsd);
2254 ddsd.dwFlags = DDSD_CAPS;
2255 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2257 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &primary, NULL);
2258 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2259 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2260 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2261 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2262 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2263 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2264 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2266 GetWindowRect(window, &r);
2267 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2268 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2269 r.left, r.top, r.right, r.bottom);
2271 expect_messages = exclusive_messages;
2275 hr = IDirectDraw4_SetDisplayMode(ddraw, 640, 480, 32, 0, 0);
2276 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2278 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
2279 expect_messages = NULL;
2280 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
2281 "Expected screen size %ux%u, got %ux%u.\n",
2282 s.right, s.bottom, screen_size.cx, screen_size.cy);
2284 GetWindowRect(window, &r);
2285 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2286 s.left, s.top, s.right, s.bottom,
2287 r.left, r.top, r.right, r.bottom);
2289 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2290 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2291 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2292 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2293 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2294 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2295 IDirectDrawSurface4_Release(primary);
2297 memset(&ddsd, 0, sizeof(ddsd));
2298 ddsd.dwSize = sizeof(ddsd);
2299 ddsd.dwFlags = DDSD_CAPS;
2300 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2302 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &primary, NULL);
2303 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2304 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2305 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2306 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
2307 s.right - s.left, ddsd.dwWidth);
2308 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
2309 s.bottom - s.top, ddsd.dwHeight);
2311 GetWindowRect(window, &r);
2312 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2313 s.left, s.top, s.right, s.bottom,
2314 r.left, r.top, r.right, r.bottom);
2316 expect_messages = exclusive_messages;
2320 hr = IDirectDraw_RestoreDisplayMode(ddraw);
2321 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
2323 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
2324 expect_messages = NULL;
2325 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
2326 "Expected screen size %ux%u, got %ux%u.\n",
2327 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
2329 GetWindowRect(window, &r);
2330 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2331 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2332 r.left, r.top, r.right, r.bottom);
2334 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2335 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2336 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
2337 s.right - s.left, ddsd.dwWidth);
2338 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
2339 s.bottom - s.top, ddsd.dwHeight);
2340 IDirectDrawSurface4_Release(primary);
2342 memset(&ddsd, 0, sizeof(ddsd));
2343 ddsd.dwSize = sizeof(ddsd);
2344 ddsd.dwFlags = DDSD_CAPS;
2345 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2347 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &primary, NULL);
2348 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2349 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2350 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2351 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2352 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2353 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2354 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2356 GetWindowRect(window, &r);
2357 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2358 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2359 r.left, r.top, r.right, r.bottom);
2361 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
2362 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2364 GetWindowRect(window, &r);
2365 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2366 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2367 r.left, r.top, r.right, r.bottom);
2369 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2370 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2371 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2372 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2373 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2374 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2375 IDirectDrawSurface4_Release(primary);
2377 memset(&ddsd, 0, sizeof(ddsd));
2378 ddsd.dwSize = sizeof(ddsd);
2379 ddsd.dwFlags = DDSD_CAPS;
2380 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2382 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &primary, NULL);
2383 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2384 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2385 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2386 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2387 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2388 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2389 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2391 GetWindowRect(window, &r);
2392 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2393 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2394 r.left, r.top, r.right, r.bottom);
2396 expect_messages = normal_messages;
2400 hr = IDirectDraw4_SetDisplayMode(ddraw, 640, 480, 32, 0, 0);
2401 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2403 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
2404 expect_messages = NULL;
2405 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
2407 GetWindowRect(window, &r);
2408 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2409 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2410 r.left, r.top, r.right, r.bottom);
2412 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2413 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2414 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2415 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2416 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2417 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2418 IDirectDrawSurface4_Release(primary);
2420 memset(&ddsd, 0, sizeof(ddsd));
2421 ddsd.dwSize = sizeof(ddsd);
2422 ddsd.dwFlags = DDSD_CAPS;
2423 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2425 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &primary, NULL);
2426 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2427 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2428 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2429 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
2430 s.right - s.left, ddsd.dwWidth);
2431 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
2432 s.bottom - s.top, ddsd.dwHeight);
2434 GetWindowRect(window, &r);
2435 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2436 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2437 r.left, r.top, r.right, r.bottom);
2439 expect_messages = normal_messages;
2443 hr = IDirectDraw_RestoreDisplayMode(ddraw);
2444 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
2446 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
2447 expect_messages = NULL;
2448 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
2450 GetWindowRect(window, &r);
2451 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2452 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2453 r.left, r.top, r.right, r.bottom);
2455 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2456 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2457 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
2458 s.right - s.left, ddsd.dwWidth);
2459 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
2460 s.bottom - s.top, ddsd.dwHeight);
2461 IDirectDrawSurface4_Release(primary);
2463 memset(&ddsd, 0, sizeof(ddsd));
2464 ddsd.dwSize = sizeof(ddsd);
2465 ddsd.dwFlags = DDSD_CAPS;
2466 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2468 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &primary, NULL);
2469 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2470 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2471 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2472 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2473 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2474 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2475 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2477 GetWindowRect(window, &r);
2478 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2479 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2480 r.left, r.top, r.right, r.bottom);
2482 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
2483 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
2484 * not DDSCL_FULLSCREEN. */
2485 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
2486 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2488 GetWindowRect(window, &r);
2489 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2490 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2491 r.left, r.top, r.right, r.bottom);
2493 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2494 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2495 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2496 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2497 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2498 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2499 IDirectDrawSurface4_Release(primary);
2501 memset(&ddsd, 0, sizeof(ddsd));
2502 ddsd.dwSize = sizeof(ddsd);
2503 ddsd.dwFlags = DDSD_CAPS;
2504 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2506 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &primary, NULL);
2507 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2508 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2509 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2510 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2511 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2512 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2513 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2515 GetWindowRect(window, &r);
2516 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2517 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2518 r.left, r.top, r.right, r.bottom);
2520 expect_messages = normal_messages;
2524 hr = IDirectDraw4_SetDisplayMode(ddraw, 640, 480, 32, 0, 0);
2525 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2527 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
2528 expect_messages = NULL;
2529 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
2531 GetWindowRect(window, &r);
2532 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2533 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2534 r.left, r.top, r.right, r.bottom);
2536 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2537 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2538 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2539 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2540 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2541 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2542 IDirectDrawSurface4_Release(primary);
2544 memset(&ddsd, 0, sizeof(ddsd));
2545 ddsd.dwSize = sizeof(ddsd);
2546 ddsd.dwFlags = DDSD_CAPS;
2547 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2549 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &primary, NULL);
2550 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2551 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2552 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2553 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
2554 s.right - s.left, ddsd.dwWidth);
2555 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
2556 s.bottom - s.top, ddsd.dwHeight);
2558 GetWindowRect(window, &r);
2559 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2560 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2561 r.left, r.top, r.right, r.bottom);
2563 expect_messages = normal_messages;
2567 hr = IDirectDraw_RestoreDisplayMode(ddraw);
2568 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
2570 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
2571 expect_messages = NULL;
2572 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
2574 GetWindowRect(window, &r);
2575 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2576 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2577 r.left, r.top, r.right, r.bottom);
2579 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2580 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2581 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
2582 s.right - s.left, ddsd.dwWidth);
2583 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
2584 s.bottom - s.top, ddsd.dwHeight);
2585 IDirectDrawSurface4_Release(primary);
2587 memset(&ddsd, 0, sizeof(ddsd));
2588 ddsd.dwSize = sizeof(ddsd);
2589 ddsd.dwFlags = DDSD_CAPS;
2590 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2592 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &primary, NULL);
2593 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2594 hr = IDirectDrawSurface4_GetSurfaceDesc(primary, &ddsd);
2595 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2596 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2597 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2598 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2599 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2600 IDirectDrawSurface4_Release(primary);
2602 GetWindowRect(window, &r);
2603 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2604 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2605 r.left, r.top, r.right, r.bottom);
2607 ref = IDirectDraw4_Release(ddraw);
2608 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2610 GetWindowRect(window, &r);
2611 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2612 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2613 r.left, r.top, r.right, r.bottom);
2615 expect_messages = NULL;
2616 DestroyWindow(window);
2617 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL));
2620 static void test_coop_level_mode_set_multi(void)
2622 IDirectDraw4 *ddraw1, *ddraw2;
2623 UINT orig_w, orig_h, w, h;
2628 if (!(ddraw1 = create_ddraw()))
2630 skip("Failed to create a ddraw object, skipping test.\n");
2634 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
2635 0, 0, 100, 100, 0, 0, 0, 0);
2637 orig_w = GetSystemMetrics(SM_CXSCREEN);
2638 orig_h = GetSystemMetrics(SM_CYSCREEN);
2640 /* With just a single ddraw object, the display mode is restored on
2642 hr = IDirectDraw4_SetDisplayMode(ddraw1, 800, 600, 32, 0, 0);
2643 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2644 w = GetSystemMetrics(SM_CXSCREEN);
2645 ok(w == 800, "Got unexpected screen width %u.\n", w);
2646 h = GetSystemMetrics(SM_CYSCREEN);
2647 ok(h == 600, "Got unexpected screen height %u.\n", h);
2649 ref = IDirectDraw4_Release(ddraw1);
2650 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2651 w = GetSystemMetrics(SM_CXSCREEN);
2652 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2653 h = GetSystemMetrics(SM_CYSCREEN);
2654 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2656 /* When there are multiple ddraw objects, the display mode is restored to
2657 * the initial mode, before the first SetDisplayMode() call. */
2658 ddraw1 = create_ddraw();
2659 hr = IDirectDraw4_SetDisplayMode(ddraw1, 800, 600, 32, 0, 0);
2660 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2661 w = GetSystemMetrics(SM_CXSCREEN);
2662 ok(w == 800, "Got unexpected screen width %u.\n", w);
2663 h = GetSystemMetrics(SM_CYSCREEN);
2664 ok(h == 600, "Got unexpected screen height %u.\n", h);
2666 ddraw2 = create_ddraw();
2667 hr = IDirectDraw4_SetDisplayMode(ddraw2, 640, 480, 32, 0, 0);
2668 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2669 w = GetSystemMetrics(SM_CXSCREEN);
2670 ok(w == 640, "Got unexpected screen width %u.\n", w);
2671 h = GetSystemMetrics(SM_CYSCREEN);
2672 ok(h == 480, "Got unexpected screen height %u.\n", h);
2674 ref = IDirectDraw4_Release(ddraw2);
2675 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2676 w = GetSystemMetrics(SM_CXSCREEN);
2677 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2678 h = GetSystemMetrics(SM_CYSCREEN);
2679 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2681 ref = IDirectDraw4_Release(ddraw1);
2682 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2683 w = GetSystemMetrics(SM_CXSCREEN);
2684 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2685 h = GetSystemMetrics(SM_CYSCREEN);
2686 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2688 /* Regardless of release ordering. */
2689 ddraw1 = create_ddraw();
2690 hr = IDirectDraw4_SetDisplayMode(ddraw1, 800, 600, 32, 0, 0);
2691 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2692 w = GetSystemMetrics(SM_CXSCREEN);
2693 ok(w == 800, "Got unexpected screen width %u.\n", w);
2694 h = GetSystemMetrics(SM_CYSCREEN);
2695 ok(h == 600, "Got unexpected screen height %u.\n", h);
2697 ddraw2 = create_ddraw();
2698 hr = IDirectDraw4_SetDisplayMode(ddraw2, 640, 480, 32, 0, 0);
2699 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2700 w = GetSystemMetrics(SM_CXSCREEN);
2701 ok(w == 640, "Got unexpected screen width %u.\n", w);
2702 h = GetSystemMetrics(SM_CYSCREEN);
2703 ok(h == 480, "Got unexpected screen height %u.\n", h);
2705 ref = IDirectDraw4_Release(ddraw1);
2706 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2707 w = GetSystemMetrics(SM_CXSCREEN);
2708 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2709 h = GetSystemMetrics(SM_CYSCREEN);
2710 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2712 ref = IDirectDraw4_Release(ddraw2);
2713 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2714 w = GetSystemMetrics(SM_CXSCREEN);
2715 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2716 h = GetSystemMetrics(SM_CYSCREEN);
2717 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2719 /* But only for ddraw objects that called SetDisplayMode(). */
2720 ddraw1 = create_ddraw();
2721 ddraw2 = create_ddraw();
2722 hr = IDirectDraw4_SetDisplayMode(ddraw2, 640, 480, 32, 0, 0);
2723 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2724 w = GetSystemMetrics(SM_CXSCREEN);
2725 ok(w == 640, "Got unexpected screen width %u.\n", w);
2726 h = GetSystemMetrics(SM_CYSCREEN);
2727 ok(h == 480, "Got unexpected screen height %u.\n", h);
2729 ref = IDirectDraw4_Release(ddraw1);
2730 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2731 w = GetSystemMetrics(SM_CXSCREEN);
2732 ok(w == 640, "Got unexpected screen width %u.\n", w);
2733 h = GetSystemMetrics(SM_CYSCREEN);
2734 ok(h == 480, "Got unexpected screen height %u.\n", h);
2736 ref = IDirectDraw4_Release(ddraw2);
2737 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2738 w = GetSystemMetrics(SM_CXSCREEN);
2739 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2740 h = GetSystemMetrics(SM_CYSCREEN);
2741 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2743 /* If there's a ddraw object that's currently in exclusive mode, it blocks
2744 * restoring the display mode. */
2745 ddraw1 = create_ddraw();
2746 hr = IDirectDraw4_SetDisplayMode(ddraw1, 800, 600, 32, 0, 0);
2747 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2748 w = GetSystemMetrics(SM_CXSCREEN);
2749 ok(w == 800, "Got unexpected screen width %u.\n", w);
2750 h = GetSystemMetrics(SM_CYSCREEN);
2751 ok(h == 600, "Got unexpected screen height %u.\n", h);
2753 ddraw2 = create_ddraw();
2754 hr = IDirectDraw4_SetDisplayMode(ddraw2, 640, 480, 32, 0, 0);
2755 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2756 w = GetSystemMetrics(SM_CXSCREEN);
2757 ok(w == 640, "Got unexpected screen width %u.\n", w);
2758 h = GetSystemMetrics(SM_CYSCREEN);
2759 ok(h == 480, "Got unexpected screen height %u.\n", h);
2761 hr = IDirectDraw4_SetCooperativeLevel(ddraw2, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2762 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2764 ref = IDirectDraw4_Release(ddraw1);
2765 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2766 w = GetSystemMetrics(SM_CXSCREEN);
2767 ok(w == 640, "Got unexpected screen width %u.\n", w);
2768 h = GetSystemMetrics(SM_CYSCREEN);
2769 ok(h == 480, "Got unexpected screen height %u.\n", h);
2771 ref = IDirectDraw4_Release(ddraw2);
2772 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2773 w = GetSystemMetrics(SM_CXSCREEN);
2774 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2775 h = GetSystemMetrics(SM_CYSCREEN);
2776 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2778 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
2779 ddraw1 = create_ddraw();
2780 hr = IDirectDraw4_SetDisplayMode(ddraw1, 800, 600, 32, 0, 0);
2781 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2782 w = GetSystemMetrics(SM_CXSCREEN);
2783 ok(w == 800, "Got unexpected screen width %u.\n", w);
2784 h = GetSystemMetrics(SM_CYSCREEN);
2785 ok(h == 600, "Got unexpected screen height %u.\n", h);
2787 hr = IDirectDraw4_SetCooperativeLevel(ddraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2788 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2790 ddraw2 = create_ddraw();
2791 hr = IDirectDraw4_SetDisplayMode(ddraw2, 640, 480, 32, 0, 0);
2792 ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr);
2794 ref = IDirectDraw4_Release(ddraw1);
2795 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2796 w = GetSystemMetrics(SM_CXSCREEN);
2797 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2798 h = GetSystemMetrics(SM_CYSCREEN);
2799 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2801 ref = IDirectDraw4_Release(ddraw2);
2802 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2803 w = GetSystemMetrics(SM_CXSCREEN);
2804 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2805 h = GetSystemMetrics(SM_CYSCREEN);
2806 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2808 DestroyWindow(window);
2811 static void test_initialize(void)
2813 IDirectDraw4 *ddraw;
2816 if (!(ddraw = create_ddraw()))
2818 skip("Failed to create a ddraw object, skipping test.\n");
2822 hr = IDirectDraw4_Initialize(ddraw, NULL);
2823 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
2824 IDirectDraw4_Release(ddraw);
2827 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw4, (void **)&ddraw);
2828 ok(SUCCEEDED(hr), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr);
2829 hr = IDirectDraw4_Initialize(ddraw, NULL);
2830 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
2831 hr = IDirectDraw4_Initialize(ddraw, NULL);
2832 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
2833 IDirectDraw4_Release(ddraw);
2837 static void test_coop_level_surf_create(void)
2839 IDirectDrawSurface4 *surface;
2840 IDirectDraw4 *ddraw;
2841 DDSURFACEDESC2 ddsd;
2844 if (!(ddraw = create_ddraw()))
2846 skip("Failed to create a ddraw object, skipping test.\n");
2850 memset(&ddsd, 0, sizeof(ddsd));
2851 ddsd.dwSize = sizeof(ddsd);
2852 ddsd.dwFlags = DDSD_CAPS;
2853 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2854 hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &surface, NULL);
2855 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
2857 IDirectDraw4_Release(ddraw);
2860 static void test_vb_discard(void)
2862 static const struct vec4 quad[] =
2864 { 0.0f, 480.0f, 0.0f, 1.0f},
2865 { 0.0f, 0.0f, 0.0f, 1.0f},
2866 {640.0f, 480.0f, 0.0f, 1.0f},
2867 {640.0f, 0.0f, 0.0f, 1.0f},
2870 IDirect3DDevice3 *device;
2872 IDirect3DVertexBuffer *buffer;
2875 D3DVERTEXBUFFERDESC desc;
2877 static const unsigned int vbsize = 16;
2880 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
2881 0, 0, 640, 480, 0, 0, 0, 0);
2883 if (!(device = create_device(window, DDSCL_NORMAL)))
2885 skip("Failed to create D3D device, skipping test.\n");
2886 DestroyWindow(window);
2890 hr = IDirect3DDevice3_GetDirect3D(device, &d3d);
2891 ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
2893 memset(&desc, 0, sizeof(desc));
2894 desc.dwSize = sizeof(desc);
2895 desc.dwCaps = D3DVBCAPS_WRITEONLY;
2896 desc.dwFVF = D3DFVF_XYZRHW;
2897 desc.dwNumVertices = vbsize;
2898 hr = IDirect3D3_CreateVertexBuffer(d3d, &desc, &buffer, 0, NULL);
2899 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
2901 hr = IDirect3DVertexBuffer_Lock(buffer, DDLOCK_DISCARDCONTENTS, (void **)&data, NULL);
2902 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
2903 memcpy(data, quad, sizeof(quad));
2904 hr = IDirect3DVertexBuffer_Unlock(buffer);
2905 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
2907 hr = IDirect3DDevice3_BeginScene(device);
2908 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2909 hr = IDirect3DDevice3_DrawPrimitiveVB(device, D3DPT_TRIANGLESTRIP, buffer, 0, 4, 0);
2910 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2911 hr = IDirect3DDevice3_EndScene(device);
2912 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2914 hr = IDirect3DVertexBuffer_Lock(buffer, DDLOCK_DISCARDCONTENTS, (void **)&data, NULL);
2915 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
2916 memset(data, 0xaa, sizeof(struct vec4) * vbsize);
2917 hr = IDirect3DVertexBuffer_Unlock(buffer);
2918 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
2920 hr = IDirect3DVertexBuffer_Lock(buffer, DDLOCK_DISCARDCONTENTS, (void **)&data, NULL);
2921 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
2922 for (i = 0; i < sizeof(struct vec4) * vbsize; i++)
2924 if (data[i] != 0xaa)
2926 ok(FALSE, "Vertex buffer data byte %u is 0x%02x, expected 0xaa\n", i, data[i]);
2930 hr = IDirect3DVertexBuffer_Unlock(buffer);
2931 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
2933 IDirect3DVertexBuffer_Release(buffer);
2934 IDirect3D3_Release(d3d);
2935 IDirect3DDevice3_Release(device);
2936 DestroyWindow(window);
2939 static void test_coop_level_multi_window(void)
2941 HWND window1, window2;
2942 IDirectDraw4 *ddraw;
2945 window1 = CreateWindowA("static", "ddraw_test1", WS_OVERLAPPEDWINDOW,
2946 0, 0, 640, 480, 0, 0, 0, 0);
2947 window2 = CreateWindowA("static", "ddraw_test2", WS_OVERLAPPEDWINDOW,
2948 0, 0, 640, 480, 0, 0, 0, 0);
2949 if (!(ddraw = create_ddraw()))
2951 skip("Failed to create a ddraw object, skipping test.\n");
2952 DestroyWindow(window2);
2953 DestroyWindow(window1);
2957 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL);
2958 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
2959 hr = IDirectDraw4_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL);
2960 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
2961 ok(IsWindow(window1), "Window 1 was destroyed.\n");
2962 ok(IsWindow(window2), "Window 2 was destroyed.\n");
2964 IDirectDraw4_Release(ddraw);
2965 DestroyWindow(window2);
2966 DestroyWindow(window1);
2969 static void test_draw_strided(void)
2971 static struct vec3 position[] =
2978 static DWORD diffuse[] =
2980 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2982 static WORD indices[] =
2987 IDirectDrawSurface4 *rt;
2988 IDirect3DDevice3 *device;
2992 D3DDRAWPRIMITIVESTRIDEDDATA strided;
2993 IDirect3DViewport3 *viewport;
2994 static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
2996 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
2997 0, 0, 640, 480, 0, 0, 0, 0);
2999 if (!(device = create_device(window, DDSCL_NORMAL)))
3001 skip("Failed to create D3D device, skipping test.\n");
3002 DestroyWindow(window);
3006 hr = IDirect3DDevice3_GetRenderTarget(device, &rt);
3007 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
3008 viewport = create_viewport(device, 0, 0, 640, 480);
3009 hr = IDirect3DDevice3_SetCurrentViewport(device, viewport);
3010 ok(SUCCEEDED(hr), "Failed to activate the viewport, hr %#x.\n", hr);
3011 hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0);
3012 ok(SUCCEEDED(hr), "Failed to clear the viewport, hr %#x.\n", hr);
3014 hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
3015 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3016 hr = IDirect3DDevice3_BeginScene(device);
3017 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3019 memset(&strided, 0x55, sizeof(strided));
3020 strided.position.lpvData = position;
3021 strided.position.dwStride = sizeof(*position);
3022 strided.diffuse.lpvData = diffuse;
3023 strided.diffuse.dwStride = sizeof(*diffuse);
3024 hr = IDirect3DDevice3_DrawIndexedPrimitiveStrided(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3025 &strided, 4, indices, 6, 0);
3026 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3028 hr = IDirect3DDevice3_EndScene(device);
3029 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3031 color = get_surface_color(rt, 320, 240);
3032 ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
3034 IDirect3DViewport3_Release(viewport);
3035 IDirectDrawSurface4_Release(rt);
3036 IDirect3DDevice3_Release(device);
3037 DestroyWindow(window);
3040 static void test_clear_rect_count(void)
3042 IDirectDrawSurface4 *rt;
3043 IDirect3DDevice3 *device;
3047 IDirect3DViewport3 *viewport;
3048 static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
3050 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
3051 0, 0, 640, 480, 0, 0, 0, 0);
3052 if (!(device = create_device(window, DDSCL_NORMAL)))
3054 skip("Failed to create D3D device, skipping test.\n");
3055 DestroyWindow(window);
3059 hr = IDirect3DDevice3_GetRenderTarget(device, &rt);
3060 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
3062 viewport = create_viewport(device, 0, 0, 640, 480);
3063 hr = IDirect3DDevice3_SetCurrentViewport(device, viewport);
3064 ok(SUCCEEDED(hr), "Failed to activate the viewport, hr %#x.\n", hr);
3065 hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0x00ffffff, 0.0f, 0);
3066 ok(SUCCEEDED(hr), "Failed to clear the viewport, hr %#x.\n", hr);
3067 hr = IDirect3DViewport3_Clear2(viewport, 0, &clear_rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
3068 ok(SUCCEEDED(hr), "Failed to clear the viewport, hr %#x.\n", hr);
3069 hr = IDirect3DViewport3_Clear2(viewport, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0f, 0);
3070 ok(SUCCEEDED(hr), "Failed to clear the viewport, hr %#x.\n", hr);
3071 hr = IDirect3DViewport3_Clear2(viewport, 1, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
3072 ok(SUCCEEDED(hr), "Failed to clear the viewport, hr %#x.\n", hr);
3074 color = get_surface_color(rt, 320, 240);
3075 ok(compare_color(color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", color);
3077 IDirect3DViewport3_Release(viewport);
3078 IDirectDrawSurface4_Release(rt);
3079 IDirect3DDevice3_Release(device);
3080 DestroyWindow(window);
3085 test_process_vertices();
3086 test_coop_level_create_device_window();
3088 test_coop_level_d3d_state();
3089 test_surface_interface_mismatch();
3090 test_coop_level_threaded();
3092 test_texture_load_ckey();
3093 test_viewport_interfaces();
3100 test_window_style();
3101 test_redundant_mode_set();
3102 test_coop_level_mode_set();
3103 test_coop_level_mode_set_multi();
3105 test_coop_level_surf_create();
3107 test_coop_level_multi_window();
3108 test_draw_strided();
3109 test_clear_rect_count();