2 * Copyright 2005 Antoine Chavasse (a.chavasse@gmail.com)
3 * Copyright 2008, 2011, 2012-2014 Stefan Dösinger for CodeWeavers
4 * Copyright 2011-2014 Henri Verbeet for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/test.h"
25 #include "wine/heap.h"
31 static BOOL is_ddraw64
= sizeof(DWORD
) != sizeof(DWORD
*);
32 static DEVMODEW registry_mode
;
34 static HRESULT (WINAPI
*pDwmIsCompositionEnabled
)(BOOL
*);
46 struct create_window_thread_param
49 HANDLE window_created
;
50 HANDLE destroy_window
;
54 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
64 if (abs(x
- y
) > ulps
)
70 static BOOL
compare_vec4(const struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
72 return compare_float(vec
->x
, x
, ulps
)
73 && compare_float(vec
->y
, y
, ulps
)
74 && compare_float(vec
->z
, z
, ulps
)
75 && compare_float(vec
->w
, w
, ulps
);
78 static BOOL
compare_uint(unsigned int x
, unsigned int y
, unsigned int max_diff
)
80 unsigned int diff
= x
> y
? x
- y
: y
- x
;
82 return diff
<= max_diff
;
85 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
87 return compare_uint(c1
& 0xff, c2
& 0xff, max_diff
)
88 && compare_uint((c1
>> 8) & 0xff, (c2
>> 8) & 0xff, max_diff
)
89 && compare_uint((c1
>> 16) & 0xff, (c2
>> 16) & 0xff, max_diff
)
90 && compare_uint((c1
>> 24) & 0xff, (c2
>> 24) & 0xff, max_diff
);
93 static void get_virtual_rect(RECT
*rect
)
95 rect
->left
= GetSystemMetrics(SM_XVIRTUALSCREEN
);
96 rect
->top
= GetSystemMetrics(SM_YVIRTUALSCREEN
);
97 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXVIRTUALSCREEN
);
98 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYVIRTUALSCREEN
);
101 /* Try to make sure pending X events have been processed before continuing */
102 static void flush_events(void)
108 time
= GetTickCount() + diff
;
111 if (MsgWaitForMultipleObjects(0, NULL
, FALSE
, 100, QS_ALLINPUT
) == WAIT_TIMEOUT
)
113 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
114 DispatchMessageA(&msg
);
115 diff
= time
- GetTickCount();
119 static BOOL
ddraw_get_identifier(IDirectDraw2
*ddraw
, DDDEVICEIDENTIFIER
*identifier
)
121 IDirectDraw4
*ddraw4
;
124 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirectDraw4
, (void **)&ddraw4
);
125 ok(SUCCEEDED(hr
), "Failed to get IDirectDraw4 interface, hr %#x.\n", hr
);
126 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw4
, identifier
, 0);
127 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#x.\n", hr
);
128 IDirectDraw4_Release(ddraw4
);
130 return SUCCEEDED(hr
);
133 static BOOL
ddraw_is_warp(IDirectDraw2
*ddraw
)
135 DDDEVICEIDENTIFIER identifier
;
137 return strcmp(winetest_platform
, "wine")
138 && ddraw_get_identifier(ddraw
, &identifier
)
139 && strstr(identifier
.szDriver
, "warp");
142 static BOOL
ddraw_is_vendor(IDirectDraw2
*ddraw
, DWORD vendor
)
144 DDDEVICEIDENTIFIER identifier
;
146 return strcmp(winetest_platform
, "wine")
147 && ddraw_get_identifier(ddraw
, &identifier
)
148 && identifier
.dwVendorId
== vendor
;
151 static BOOL
ddraw_is_intel(IDirectDraw2
*ddraw
)
153 return ddraw_is_vendor(ddraw
, 0x8086);
156 static BOOL
ddraw_is_nvidia(IDirectDraw2
*ddraw
)
158 return ddraw_is_vendor(ddraw
, 0x10de);
161 static BOOL
ddraw_is_vmware(IDirectDraw2
*ddraw
)
163 return ddraw_is_vendor(ddraw
, 0x15ad);
166 static BOOL
is_software_device_type(const GUID
*device_guid
)
168 return device_guid
!= &IID_IDirect3DHALDevice
;
171 static IDirectDrawSurface
*create_overlay(IDirectDraw2
*ddraw
,
172 unsigned int width
, unsigned int height
, DWORD format
)
174 IDirectDrawSurface
*surface
;
177 memset(&desc
, 0, sizeof(desc
));
178 desc
.dwSize
= sizeof(desc
);
179 desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
180 desc
.dwWidth
= width
;
181 desc
.dwHeight
= height
;
182 desc
.ddsCaps
.dwCaps
= DDSCAPS_OVERLAY
;
183 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
184 desc
.ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
185 desc
.ddpfPixelFormat
.dwFourCC
= format
;
187 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &desc
, &surface
, NULL
)))
192 static HWND
create_window(void)
194 RECT r
= {0, 0, 640, 480};
196 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
198 return CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
199 CW_USEDEFAULT
, CW_USEDEFAULT
, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
202 static DWORD WINAPI
create_window_thread_proc(void *param
)
204 struct create_window_thread_param
*p
= param
;
208 p
->window
= create_window();
209 ret
= SetEvent(p
->window_created
);
210 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
216 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
217 DispatchMessageA(&msg
);
218 res
= WaitForSingleObject(p
->destroy_window
, 100);
219 if (res
== WAIT_OBJECT_0
)
221 if (res
!= WAIT_TIMEOUT
)
223 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
228 DestroyWindow(p
->window
);
233 static void create_window_thread(struct create_window_thread_param
*p
)
237 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
238 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
239 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
240 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
241 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
242 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
243 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
244 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
247 static void destroy_window_thread(struct create_window_thread_param
*p
)
249 SetEvent(p
->destroy_window
);
250 WaitForSingleObject(p
->thread
, INFINITE
);
251 CloseHandle(p
->destroy_window
);
252 CloseHandle(p
->window_created
);
253 CloseHandle(p
->thread
);
256 static IDirectDrawSurface
*get_depth_stencil(IDirect3DDevice2
*device
)
258 IDirectDrawSurface
*rt
, *ret
;
259 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
262 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
263 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
264 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ret
);
265 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
266 IDirectDrawSurface_Release(rt
);
270 /* Free original_modes after finished using it */
271 static BOOL
save_display_modes(DEVMODEW
**original_modes
, unsigned int *display_count
)
273 unsigned int number
, size
= 2, count
= 0, index
= 0;
274 DISPLAY_DEVICEW display_device
;
275 DEVMODEW
*modes
, *tmp
;
277 if (!(modes
= heap_alloc(size
* sizeof(*modes
))))
280 display_device
.cb
= sizeof(display_device
);
281 while (EnumDisplayDevicesW(NULL
, index
++, &display_device
, 0))
283 /* Skip software devices */
284 if (swscanf(display_device
.DeviceName
, L
"\\\\.\\DISPLAY%u", &number
) != 1)
287 if (!(display_device
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
))
293 if (!(tmp
= heap_realloc(modes
, size
* sizeof(*modes
))))
301 memset(&modes
[count
], 0, sizeof(modes
[count
]));
302 modes
[count
].dmSize
= sizeof(modes
[count
]);
303 if (!EnumDisplaySettingsW(display_device
.DeviceName
, ENUM_CURRENT_SETTINGS
, &modes
[count
]))
309 lstrcpyW(modes
[count
++].dmDeviceName
, display_device
.DeviceName
);
312 *original_modes
= modes
;
313 *display_count
= count
;
317 static BOOL
restore_display_modes(DEVMODEW
*modes
, unsigned int count
)
322 for (index
= 0; index
< count
; ++index
)
324 ret
= ChangeDisplaySettingsExW(modes
[index
].dmDeviceName
, &modes
[index
], NULL
,
325 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
326 if (ret
!= DISP_CHANGE_SUCCESSFUL
)
329 ret
= ChangeDisplaySettingsExW(NULL
, NULL
, NULL
, 0, NULL
);
330 return ret
== DISP_CHANGE_SUCCESSFUL
;
333 static HRESULT
set_display_mode(IDirectDraw2
*ddraw
, DWORD width
, DWORD height
)
335 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
337 return IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0);
340 static D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
342 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
343 DDSURFACEDESC surface_desc
;
347 memset(&surface_desc
, 0, sizeof(surface_desc
));
348 surface_desc
.dwSize
= sizeof(surface_desc
);
350 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
351 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
355 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
357 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
358 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
363 static void fill_surface(IDirectDrawSurface
*surface
, D3DCOLOR color
)
365 DDSURFACEDESC surface_desc
= {sizeof(surface_desc
)};
370 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
371 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
373 for (y
= 0; y
< surface_desc
.dwHeight
; ++y
)
375 ptr
= (DWORD
*)((BYTE
*)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
);
376 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
382 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
383 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
386 static void check_rect(IDirectDrawSurface
*surface
, RECT r
, const char *message
)
388 LONG x_coords
[2][2] =
390 {r
.left
- 1, r
.left
+ 1},
391 {r
.right
+ 1, r
.right
- 1},
393 LONG y_coords
[2][2] =
395 {r
.top
- 1, r
.top
+ 1},
396 {r
.bottom
+ 1, r
.bottom
- 1}
398 unsigned int i
, j
, x_side
, y_side
;
402 for (i
= 0; i
< 2; ++i
)
404 for (j
= 0; j
< 2; ++j
)
406 for (x_side
= 0; x_side
< 2; ++x_side
)
408 for (y_side
= 0; y_side
< 2; ++y_side
)
410 DWORD expected
= (x_side
== 1 && y_side
== 1) ? 0x00ffffff : 0x00000000;
412 x
= x_coords
[i
][x_side
];
413 y
= y_coords
[j
][y_side
];
414 if (x
< 0 || x
>= 640 || y
< 0 || y
>= 480)
416 color
= get_surface_color(surface
, x
, y
);
417 ok(color
== expected
, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
418 message
, x
, y
, color
, expected
);
425 static DWORD
get_device_z_depth(IDirect3DDevice2
*device
)
427 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
428 IDirectDrawSurface
*ds
, *rt
;
432 if (FAILED(IDirect3DDevice2_GetRenderTarget(device
, &rt
)))
435 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ds
);
436 IDirectDrawSurface_Release(rt
);
440 desc
.dwSize
= sizeof(desc
);
441 hr
= IDirectDrawSurface_GetSurfaceDesc(ds
, &desc
);
442 IDirectDrawSurface_Release(ds
);
446 return U2(desc
).dwZBufferBitDepth
;
449 static IDirectDraw2
*create_ddraw(void)
451 IDirectDraw2
*ddraw2
;
455 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
458 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw2
);
459 IDirectDraw_Release(ddraw1
);
466 static IDirect3DDevice2
*create_device_ex(IDirectDraw2
*ddraw
, HWND window
, DWORD coop_level
, const GUID
*device_guid
)
468 /* Prefer 16 bit depth buffers because Nvidia gives us an unpadded D24 buffer if we ask
469 * for 24 bit and handles such buffers incorrectly in DDBLT_DEPTHFILL. AMD only supports
470 * 16 bit buffers in ddraw1/2. Stencil was added in ddraw4, so we cannot create a D24S8
472 static const DWORD z_depths
[] = {16, 32, 24};
473 IDirectDrawSurface
*surface
, *ds
;
474 IDirect3DDevice2
*device
= NULL
;
475 DDSURFACEDESC surface_desc
;
480 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, coop_level
);
481 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
483 memset(&surface_desc
, 0, sizeof(surface_desc
));
484 surface_desc
.dwSize
= sizeof(surface_desc
);
485 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
486 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
487 if (is_software_device_type(device_guid
))
488 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
489 surface_desc
.dwWidth
= 640;
490 surface_desc
.dwHeight
= 480;
492 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
493 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
495 if (coop_level
& DDSCL_NORMAL
)
497 IDirectDrawClipper
*clipper
;
499 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
500 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
501 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
502 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
503 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
504 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
505 IDirectDrawClipper_Release(clipper
);
508 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
511 IDirectDrawSurface_Release(surface
);
515 /* We used to use EnumDevices() for this, but it seems
516 * D3DDEVICEDESC.dwDeviceZBufferBitDepth only has a very casual
517 * relationship with reality. */
518 for (i
= 0; i
< ARRAY_SIZE(z_depths
); ++i
)
520 memset(&surface_desc
, 0, sizeof(surface_desc
));
521 surface_desc
.dwSize
= sizeof(surface_desc
);
522 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
523 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
524 if (is_software_device_type(device_guid
))
525 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
526 U2(surface_desc
).dwZBufferBitDepth
= z_depths
[i
];
527 surface_desc
.dwWidth
= 640;
528 surface_desc
.dwHeight
= 480;
529 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
)))
532 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
533 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
534 IDirectDrawSurface_Release(ds
);
538 if (SUCCEEDED(IDirect3D2_CreateDevice(d3d
, device_guid
, surface
, &device
)))
541 IDirectDrawSurface_DeleteAttachedSurface(surface
, 0, ds
);
544 IDirect3D2_Release(d3d
);
545 IDirectDrawSurface_Release(surface
);
549 static IDirect3DDevice2
*create_device(IDirectDraw2
*ddraw
, HWND window
, DWORD coop_level
)
551 return create_device_ex(ddraw
, window
, coop_level
, &IID_IDirect3DHALDevice
);
554 static IDirect3DViewport2
*create_viewport(IDirect3DDevice2
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
556 IDirect3DViewport2
*viewport
;
561 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
562 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
563 hr
= IDirect3D2_CreateViewport(d3d
, &viewport
, NULL
);
564 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
565 hr
= IDirect3DDevice2_AddViewport(device
, viewport
);
566 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
567 memset(&vp
, 0, sizeof(vp
));
568 vp
.dwSize
= sizeof(vp
);
575 vp
.dvClipWidth
= 2.0f
;
576 vp
.dvClipHeight
= 2.0f
;
579 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp
);
580 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
581 IDirect3D2_Release(d3d
);
586 static void viewport_set_background(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
,
587 IDirect3DMaterial2
*material
)
589 D3DMATERIALHANDLE material_handle
;
592 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &material_handle
);
593 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
594 hr
= IDirect3DViewport2_SetBackground(viewport
, material_handle
);
595 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
598 static void destroy_viewport(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
)
602 hr
= IDirect3DDevice2_DeleteViewport(device
, viewport
);
603 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
604 IDirect3DViewport2_Release(viewport
);
607 static IDirect3DMaterial2
*create_material(IDirect3DDevice2
*device
, D3DMATERIAL
*mat
)
609 IDirect3DMaterial2
*material
;
613 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
614 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
615 hr
= IDirect3D2_CreateMaterial(d3d
, &material
, NULL
);
616 ok(SUCCEEDED(hr
), "Failed to create material, hr %#x.\n", hr
);
617 hr
= IDirect3DMaterial2_SetMaterial(material
, mat
);
618 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
619 IDirect3D2_Release(d3d
);
624 static IDirect3DMaterial2
*create_diffuse_material(IDirect3DDevice2
*device
, float r
, float g
, float b
, float a
)
628 memset(&mat
, 0, sizeof(mat
));
629 mat
.dwSize
= sizeof(mat
);
630 U1(U(mat
).diffuse
).r
= r
;
631 U2(U(mat
).diffuse
).g
= g
;
632 U3(U(mat
).diffuse
).b
= b
;
633 U4(U(mat
).diffuse
).a
= a
;
635 return create_material(device
, &mat
);
638 static IDirect3DMaterial2
*create_diffuse_and_ambient_material(IDirect3DDevice2
*device
,
639 float r
, float g
, float b
, float a
)
643 memset(&mat
, 0, sizeof(mat
));
644 mat
.dwSize
= sizeof(mat
);
645 U1(U(mat
).diffuse
).r
= r
;
646 U2(U(mat
).diffuse
).g
= g
;
647 U3(U(mat
).diffuse
).b
= b
;
648 U4(U(mat
).diffuse
).a
= a
;
650 U1(U(mat
).ambient
).r
= r
;
651 U2(U(mat
).ambient
).g
= g
;
652 U3(U(mat
).ambient
).b
= b
;
653 U4(U(mat
).ambient
).a
= a
;
655 return create_material(device
, &mat
);
658 static IDirect3DMaterial2
*create_specular_material(IDirect3DDevice2
*device
,
659 float r
, float g
, float b
, float a
, float power
)
663 memset(&mat
, 0, sizeof(mat
));
664 mat
.dwSize
= sizeof(mat
);
665 U1(U2(mat
).specular
).r
= r
;
666 U2(U2(mat
).specular
).g
= g
;
667 U3(U2(mat
).specular
).b
= b
;
668 U4(U2(mat
).specular
).a
= a
;
669 U4(mat
).power
= power
;
671 return create_material(device
, &mat
);
674 static IDirect3DMaterial2
*create_emissive_material(IDirect3DDevice2
*device
, float r
, float g
, float b
, float a
)
678 memset(&mat
, 0, sizeof(mat
));
679 mat
.dwSize
= sizeof(mat
);
680 U1(U3(mat
).emissive
).r
= r
;
681 U2(U3(mat
).emissive
).g
= g
;
682 U3(U3(mat
).emissive
).b
= b
;
683 U4(U3(mat
).emissive
).a
= a
;
685 return create_material(device
, &mat
);
688 static void destroy_material(IDirect3DMaterial2
*material
)
690 IDirect3DMaterial2_Release(material
);
697 WPARAM expect_wparam
;
700 static const struct message
*expect_messages
;
702 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
704 if (expect_messages
&& message
== expect_messages
->message
)
706 if (expect_messages
->check_wparam
)
707 ok (wparam
== expect_messages
->expect_wparam
,
708 "Got unexpected wparam %lx for message %x, expected %lx.\n",
709 wparam
, message
, expect_messages
->expect_wparam
);
714 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
717 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
718 * interface. This prevents subsequent SetCooperativeLevel() calls on a
719 * different window from failing with DDERR_HWNDALREADYSET. */
720 static void fix_wndproc(HWND window
, LONG_PTR proc
)
725 if (!(ddraw
= create_ddraw()))
728 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
729 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
730 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
731 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
732 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
734 IDirectDraw2_Release(ddraw
);
737 static HRESULT CALLBACK
restore_callback(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
739 HRESULT hr
= IDirectDrawSurface_Restore(surface
);
740 ok(SUCCEEDED(hr
) || hr
== DDERR_IMPLICITLYCREATED
, "Failed to restore surface, hr %#x.\n", hr
);
741 IDirectDrawSurface_Release(surface
);
746 static HRESULT
restore_surfaces(IDirectDraw2
*ddraw
)
748 return IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
,
749 NULL
, NULL
, restore_callback
);
752 static void test_coop_level_create_device_window(void)
754 HWND focus_window
, device_window
;
758 focus_window
= create_window();
759 ddraw
= create_ddraw();
760 ok(!!ddraw
, "Failed to create a ddraw object.\n");
762 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
763 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
764 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
765 ok(!device_window
, "Unexpected device window found.\n");
766 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
767 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
768 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
769 ok(!device_window
, "Unexpected device window found.\n");
770 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
771 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
772 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
773 ok(!device_window
, "Unexpected device window found.\n");
774 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
775 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
776 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
777 ok(!device_window
, "Unexpected device window found.\n");
778 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
779 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
780 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
781 ok(!device_window
, "Unexpected device window found.\n");
783 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
784 if (broken(hr
== DDERR_INVALIDPARAMS
))
786 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
787 IDirectDraw2_Release(ddraw
);
788 DestroyWindow(focus_window
);
792 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
793 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
794 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
795 ok(!device_window
, "Unexpected device window found.\n");
796 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
797 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
798 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
799 ok(!device_window
, "Unexpected device window found.\n");
801 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
802 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
803 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
804 ok(!device_window
, "Unexpected device window found.\n");
805 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
806 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
807 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
808 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
809 ok(!!device_window
, "Device window not found.\n");
811 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
812 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
813 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
814 ok(!device_window
, "Unexpected device window found.\n");
815 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
816 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
817 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
818 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
819 ok(!!device_window
, "Device window not found.\n");
821 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
822 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
823 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
824 ok(!device_window
, "Unexpected device window found.\n");
825 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
826 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
827 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
828 ok(!device_window
, "Unexpected device window found.\n");
829 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
830 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
831 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
832 ok(!device_window
, "Unexpected device window found.\n");
833 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
834 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
835 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
836 ok(!!device_window
, "Device window not found.\n");
838 IDirectDraw2_Release(ddraw
);
839 DestroyWindow(focus_window
);
842 static void test_clipper_blt(void)
844 IDirectDrawSurface
*src_surface
, *dst_surface
;
845 RECT client_rect
, src_rect
;
846 IDirectDrawClipper
*clipper
;
847 DDSURFACEDESC surface_desc
;
848 unsigned int i
, j
, x
, y
;
860 static const DWORD src_data
[] =
862 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
863 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
864 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
866 static const D3DCOLOR expected1
[] =
868 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
869 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
870 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
871 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
873 /* Nvidia on Windows seems to have an off-by-one error
874 * when processing source rectangles. Our left = 1 and
875 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
876 * read as well, but only for the edge pixels on the
877 * output image. The bug happens on the y axis as well,
878 * but we only read one row there, and all source rows
879 * contain the same data. This bug is not dependent on
880 * the presence of a clipper. */
881 static const D3DCOLOR expected1_broken
[] =
883 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
884 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
885 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
886 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
888 static const D3DCOLOR expected2
[] =
890 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
891 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
892 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
893 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
896 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
897 10, 10, 640, 480, 0, 0, 0, 0);
898 ShowWindow(window
, SW_SHOW
);
899 ddraw
= create_ddraw();
900 ok(!!ddraw
, "Failed to create a ddraw object.\n");
902 ret
= GetClientRect(window
, &client_rect
);
903 ok(ret
, "Failed to get client rect.\n");
904 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
905 ok(ret
, "Failed to map client rect.\n");
907 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
908 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
910 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
911 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
912 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
913 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
914 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
915 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
916 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
917 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
918 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
919 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
920 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
921 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
922 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
923 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
924 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
925 "Got unexpected bounding rect %s, expected %s.\n",
926 wine_dbgstr_rect(&rgn_data
->rdh
.rcBound
), wine_dbgstr_rect(&client_rect
));
927 HeapFree(GetProcessHeap(), 0, rgn_data
);
929 r1
= CreateRectRgn(0, 0, 320, 240);
930 ok(!!r1
, "Failed to create region.\n");
931 r2
= CreateRectRgn(320, 240, 640, 480);
932 ok(!!r2
, "Failed to create region.\n");
933 CombineRgn(r1
, r1
, r2
, RGN_OR
);
934 ret
= GetRegionData(r1
, 0, NULL
);
935 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
936 ret
= GetRegionData(r1
, ret
, rgn_data
);
937 ok(!!ret
, "Failed to get region data.\n");
942 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
943 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
944 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
945 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
946 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
947 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
949 HeapFree(GetProcessHeap(), 0, rgn_data
);
951 memset(&surface_desc
, 0, sizeof(surface_desc
));
952 surface_desc
.dwSize
= sizeof(surface_desc
);
953 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
954 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
955 surface_desc
.dwWidth
= 640;
956 surface_desc
.dwHeight
= 480;
957 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
958 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
959 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
960 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
961 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
962 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
964 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
965 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
966 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
967 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
969 memset(&fx
, 0, sizeof(fx
));
970 fx
.dwSize
= sizeof(fx
);
971 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
972 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
973 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
974 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
976 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
977 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
978 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
979 ptr
= surface_desc
.lpSurface
;
980 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
981 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
982 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
983 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
984 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
986 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
987 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
989 SetRect(&src_rect
, 1, 1, 5, 2);
990 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
991 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
992 for (i
= 0; i
< 4; ++i
)
994 for (j
= 0; j
< 4; ++j
)
996 x
= 80 * ((2 * j
) + 1);
997 y
= 60 * ((2 * i
) + 1);
998 color
= get_surface_color(dst_surface
, x
, y
);
999 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
1000 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
1001 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
1005 U5(fx
).dwFillColor
= 0xff0000ff;
1006 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1007 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
1008 for (i
= 0; i
< 4; ++i
)
1010 for (j
= 0; j
< 4; ++j
)
1012 x
= 80 * ((2 * j
) + 1);
1013 y
= 60 * ((2 * i
) + 1);
1014 color
= get_surface_color(dst_surface
, x
, y
);
1015 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
1016 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
1020 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
1021 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#x.\n", hr
);
1023 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1024 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
1025 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1026 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
1027 DestroyWindow(window
);
1028 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1029 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
1030 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1031 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
1032 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1033 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
1034 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
1035 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
1036 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1037 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
1038 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1039 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
1041 IDirectDrawSurface_Release(dst_surface
);
1042 IDirectDrawSurface_Release(src_surface
);
1043 refcount
= IDirectDrawClipper_Release(clipper
);
1044 ok(!refcount
, "Clipper has %u references left.\n", refcount
);
1045 IDirectDraw2_Release(ddraw
);
1048 static void test_coop_level_d3d_state(void)
1050 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1051 IDirectDrawSurface
*rt
, *surface
;
1052 IDirect3DMaterial2
*background
;
1053 IDirect3DViewport2
*viewport
;
1054 IDirect3DDevice2
*device
;
1055 D3DMATERIAL material
;
1056 IDirectDraw2
*ddraw
;
1063 static D3DLVERTEX quad
[] =
1065 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0x800000ff}},
1066 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0x800000ff}},
1067 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0x800000ff}},
1068 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0x800000ff}},
1071 window
= create_window();
1072 ddraw
= create_ddraw();
1073 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1074 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1076 skip("Failed to create a 3D device, skipping test.\n");
1077 IDirectDraw2_Release(ddraw
);
1078 DestroyWindow(window
);
1082 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1083 viewport
= create_viewport(device
, 0, 0, 640, 480);
1084 viewport_set_background(device
, viewport
, background
);
1086 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1087 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1088 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
1089 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1091 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1092 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1093 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1094 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1095 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
1096 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1097 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1098 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
1099 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
1100 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1101 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1102 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1103 color
= get_surface_color(rt
, 320, 240);
1104 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1106 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1107 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1108 hr
= IDirectDrawSurface_IsLost(rt
);
1109 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
1111 memset(&lock
, 0, sizeof(lock
));
1112 lock
.dwSize
= sizeof(lock
);
1113 lock
.lpSurface
= (void *)0xdeadbeef;
1114 hr
= IDirectDrawSurface2_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1115 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
1116 ok(lock
.lpSurface
== (void *)0xdeadbeef, "Got unexpected lock.lpSurface %p.\n", lock
.lpSurface
);
1118 hr
= restore_surfaces(ddraw
);
1119 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1121 hr
= IDirectDrawSurface2_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1122 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1123 hr
= IDirectDrawSurface2_Unlock(rt
, NULL
);
1124 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1126 memset(&material
, 0, sizeof(material
));
1127 material
.dwSize
= sizeof(material
);
1128 U1(U(material
).diffuse
).r
= 0.0f
;
1129 U2(U(material
).diffuse
).g
= 1.0f
;
1130 U3(U(material
).diffuse
).b
= 0.0f
;
1131 U4(U(material
).diffuse
).a
= 1.0f
;
1132 hr
= IDirect3DMaterial2_SetMaterial(background
, &material
);
1133 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1135 hr
= IDirect3DDevice2_GetRenderTarget(device
, &surface
);
1136 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1137 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
1138 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1139 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1140 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
1141 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1142 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1143 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
1144 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
1145 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1146 color
= get_surface_color(rt
, 320, 240);
1147 ok(compare_color(color
, 0x0000ff00, 1) || broken(compare_color(color
, 0x00000000, 1)),
1148 "Got unexpected color 0x%08x.\n", color
);
1150 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1151 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1152 hr
= IDirect3DDevice2_BeginScene(device
);
1153 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1154 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, ARRAY_SIZE(quad
), 0);
1155 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1156 hr
= IDirect3DDevice2_EndScene(device
);
1157 ok(hr
== DD_OK
|| broken(ddraw_is_warp(ddraw
) && hr
== DDERR_SURFACELOST
), "Got unexpected hr %#x.\n", hr
);
1160 color
= get_surface_color(rt
, 320, 240);
1161 ok(compare_color(color
, 0x0000ff80, 1), "Got unexpected color 0x%08x.\n", color
);
1164 destroy_viewport(device
, viewport
);
1165 destroy_material(background
);
1166 IDirectDrawSurface_Release(surface
);
1167 IDirectDrawSurface_Release(rt
);
1168 IDirect3DDevice2_Release(device
);
1169 IDirectDraw2_Release(ddraw
);
1170 DestroyWindow(window
);
1173 static void test_surface_interface_mismatch(void)
1175 IDirectDraw2
*ddraw
= NULL
;
1176 IDirect3D2
*d3d
= NULL
;
1177 IDirectDrawSurface
*surface
= NULL
, *ds
;
1178 IDirectDrawSurface3
*surface3
= NULL
;
1179 IDirect3DDevice2
*device
= NULL
;
1180 IDirect3DViewport2
*viewport
= NULL
;
1181 IDirect3DMaterial2
*background
= NULL
;
1182 DDSURFACEDESC surface_desc
;
1188 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1190 window
= create_window();
1191 ddraw
= create_ddraw();
1192 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1193 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1195 skip("Failed to create a 3D device, skipping test.\n");
1196 IDirectDraw2_Release(ddraw
);
1197 DestroyWindow(window
);
1200 z_depth
= get_device_z_depth(device
);
1201 ok(!!z_depth
, "Failed to get device z depth.\n");
1202 IDirect3DDevice2_Release(device
);
1205 memset(&surface_desc
, 0, sizeof(surface_desc
));
1206 surface_desc
.dwSize
= sizeof(surface_desc
);
1207 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1208 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
1209 surface_desc
.dwWidth
= 640;
1210 surface_desc
.dwHeight
= 480;
1212 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1213 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1215 hr
= IDirectDrawSurface2_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
1218 skip("Failed to get the IDirectDrawSurface3 interface, skipping test.\n");
1222 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
1224 skip("D3D interface is not available, skipping test.\n");
1228 memset(&surface_desc
, 0, sizeof(surface_desc
));
1229 surface_desc
.dwSize
= sizeof(surface_desc
);
1230 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
1231 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1232 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
1233 surface_desc
.dwWidth
= 640;
1234 surface_desc
.dwHeight
= 480;
1235 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
1236 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
1240 /* Using a different surface interface version still works */
1241 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
1242 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
1243 refcount
= IDirectDrawSurface_Release(ds
);
1244 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
1249 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface
*)surface3
, &device
);
1250 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
1254 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1255 viewport
= create_viewport(device
, 0, 0, 640, 480);
1256 viewport_set_background(device
, viewport
, background
);
1258 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1259 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1260 color
= get_surface_color(surface
, 320, 240);
1261 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1265 destroy_viewport(device
, viewport
);
1267 destroy_material(background
);
1268 if (surface3
) IDirectDrawSurface3_Release(surface3
);
1269 if (surface
) IDirectDrawSurface_Release(surface
);
1270 if (device
) IDirect3DDevice2_Release(device
);
1271 if (d3d
) IDirect3D2_Release(d3d
);
1272 if (ddraw
) IDirectDraw2_Release(ddraw
);
1273 DestroyWindow(window
);
1276 static void test_coop_level_threaded(void)
1278 struct create_window_thread_param p
;
1279 IDirectDraw2
*ddraw
;
1282 ddraw
= create_ddraw();
1283 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1284 create_window_thread(&p
);
1286 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1287 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1289 destroy_window_thread(&p
);
1290 IDirectDraw2_Release(ddraw
);
1293 static void test_depth_blit(const GUID
*device_guid
)
1295 static D3DLVERTEX quad1
[] =
1297 {{-1.0}, { 1.0}, {0.50f
}, 0, {0xff00ff00}},
1298 {{ 1.0}, { 1.0}, {0.50f
}, 0, {0xff00ff00}},
1299 {{-1.0}, {-1.0}, {0.50f
}, 0, {0xff00ff00}},
1300 {{ 1.0}, {-1.0}, {0.50f
}, 0, {0xff00ff00}},
1302 static const D3DCOLOR expected_colors
[4][4] =
1304 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1305 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1306 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1307 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1309 DDSURFACEDESC ddsd_new
, ddsd_existing
;
1311 IDirect3DDevice2
*device
;
1312 IDirectDrawSurface
*ds1
, *ds2
, *ds3
, *rt
;
1313 BOOL depth_fill_broken
= FALSE
;
1314 IDirect3DViewport2
*viewport
;
1315 RECT src_rect
, dst_rect
;
1319 IDirectDraw2
*ddraw
;
1323 IDirect3DMaterial2
*background
;
1325 window
= create_window();
1326 ddraw
= create_ddraw();
1327 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1328 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
1330 skip("Failed to create a 3D device, skipping test.\n");
1331 IDirectDraw2_Release(ddraw
);
1332 DestroyWindow(window
);
1336 ds1
= get_depth_stencil(device
);
1338 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1339 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1340 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1341 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1342 hr
= IDirectDrawSurface_GetSurfaceDesc(ds1
, &ddsd_existing
);
1343 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1344 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1345 if (is_software_device_type(device_guid
))
1346 ddsd_new
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
1347 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1348 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1349 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1350 ddsd_new
.ddpfPixelFormat
= ddsd_existing
.ddpfPixelFormat
;
1351 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1352 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1353 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1354 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1356 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1357 viewport
= create_viewport(device
, 0, 0, ddsd_existing
.dwWidth
, ddsd_existing
.dwHeight
);
1358 viewport_set_background(device
, viewport
, background
);
1359 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1360 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
1362 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1363 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
1364 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1365 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
1367 U1(d3drect
).x1
= U2(d3drect
).y1
= 0;
1368 U3(d3drect
).x2
= ddsd_existing
.dwWidth
; U4(d3drect
).y2
= ddsd_existing
.dwHeight
;
1369 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
);
1370 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
1373 SetRect(&src_rect
, 0, 0, 320, 240);
1374 SetRect(&dst_rect
, 0, 0, 320, 240);
1375 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1376 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1377 /* Different locations. */
1378 SetRect(&src_rect
, 0, 0, 320, 240);
1379 SetRect(&dst_rect
, 320, 240, 640, 480);
1380 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1381 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1383 SetRect(&src_rect
, 0, 0, 320, 240);
1384 SetRect(&dst_rect
, 0, 0, 640, 480);
1385 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1386 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1388 SetRect(&src_rect
, 0, 480, 640, 0);
1389 SetRect(&dst_rect
, 0, 0, 640, 480);
1390 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1391 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1392 SetRect(&src_rect
, 0, 0, 640, 480);
1393 SetRect(&dst_rect
, 0, 480, 640, 0);
1394 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1395 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1396 /* Full, explicit. */
1397 SetRect(&src_rect
, 0, 0, 640, 480);
1398 SetRect(&dst_rect
, 0, 0, 640, 480);
1399 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1400 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1401 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1403 /* Depth blit inside a BeginScene / EndScene pair */
1404 hr
= IDirect3DDevice2_BeginScene(device
);
1405 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1406 /* From the current depth stencil */
1407 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1408 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1409 /* To the current depth stencil */
1410 hr
= IDirectDrawSurface_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1411 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1412 /* Between unbound surfaces */
1413 hr
= IDirectDrawSurface_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1414 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1415 hr
= IDirect3DDevice2_EndScene(device
);
1416 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1418 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1419 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1420 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1421 * a reliable result(z = 0.0) */
1422 memset(&fx
, 0, sizeof(fx
));
1423 fx
.dwSize
= sizeof(fx
);
1424 U5(fx
).dwFillDepth
= 0;
1425 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1426 ok(hr
== D3D_OK
|| broken(is_software_device_type(device_guid
)
1427 && hr
== 0x8876086c /* D3DERR_INVALIDCALL */), "Got unexpected hr %#x.\n", hr
);
1429 depth_fill_broken
= TRUE
;
1431 /* This clears the Z buffer with 1.0 */
1432 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
);
1433 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1435 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1436 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1438 color
= get_surface_color(rt
, 80, 60);
1439 /* For some reason clears and colour fill blits randomly fail with software render target. */
1440 ok(color
== 0x00ff0000 || broken(is_software_device_type(device_guid
) && !color
),
1441 "Got unexpected colour 0x%08x.\n", color
);
1444 fill_surface(rt
, 0xffff0000);
1446 color
= get_surface_color(rt
, 80, 60);
1447 ok(color
== 0x00ff0000, "Got unexpected colour 0x%08x.\n", color
);
1450 SetRect(&dst_rect
, 0, 0, 320, 240);
1451 hr
= IDirectDrawSurface_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1452 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1453 IDirectDrawSurface_Release(ds3
);
1454 IDirectDrawSurface_Release(ds2
);
1455 IDirectDrawSurface_Release(ds1
);
1457 hr
= IDirect3DDevice2_BeginScene(device
);
1458 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1459 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad1
, 4, 0);
1460 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1461 hr
= IDirect3DDevice2_EndScene(device
);
1462 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1464 for (i
= 0; i
< 4; ++i
)
1466 for (j
= 0; j
< 4; ++j
)
1468 unsigned int x
= 80 * ((2 * j
) + 1);
1469 unsigned int y
= 60 * ((2 * i
) + 1);
1470 color
= get_surface_color(rt
, x
, y
);
1471 ok(compare_color(color
, expected_colors
[i
][j
], 1) || broken(depth_fill_broken
&& color
== 0x0000ff00),
1472 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1475 IDirectDrawSurface_Release(rt
);
1477 destroy_viewport(device
, viewport
);
1478 destroy_material(background
);
1479 IDirect3DDevice2_Release(device
);
1480 IDirectDraw2_Release(ddraw
);
1481 DestroyWindow(window
);
1484 static void test_texture_load_ckey(void)
1486 IDirectDraw2
*ddraw
= NULL
;
1487 IDirectDrawSurface
*src
= NULL
;
1488 IDirectDrawSurface
*dst
= NULL
;
1489 IDirect3DTexture
*src_tex
= NULL
;
1490 IDirect3DTexture
*dst_tex
= NULL
;
1495 ddraw
= create_ddraw();
1496 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1497 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1498 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1500 memset(&ddsd
, 0, sizeof(ddsd
));
1501 ddsd
.dwSize
= sizeof(ddsd
);
1502 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1503 ddsd
.dwHeight
= 128;
1505 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1506 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1507 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1508 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1509 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1510 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1512 hr
= IDirectDrawSurface_QueryInterface(src
, &IID_IDirect3DTexture
, (void **)&src_tex
);
1513 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get Direct3DTexture interface, hr %#x.\n", hr
);
1516 /* 64 bit ddraw does not support d3d */
1517 skip("Could not get Direct3DTexture interface, skipping texture::Load color keying tests.\n");
1520 hr
= IDirectDrawSurface_QueryInterface(dst
, &IID_IDirect3DTexture
, (void **)&dst_tex
);
1521 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture interface, hr %#x.\n", hr
);
1523 /* No surface has a color key */
1524 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1525 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDCAPS
), "Got unexpected hr %#x.\n", hr
);
1528 /* Testbot Windows NT VMs */
1529 skip("IDirect3DTexture::Load does not work, skipping color keying tests.\n");
1533 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1534 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1535 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1536 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1537 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1539 /* Source surface has a color key */
1540 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1541 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1542 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1543 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1544 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1545 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1546 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1547 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1548 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1550 /* Both surfaces have a color key: Dest ckey is overwritten */
1551 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1552 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1553 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1554 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1555 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1556 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1557 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1558 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1559 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1561 /* Only the destination has a color key: It is not deleted */
1562 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1563 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1564 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1565 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1566 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1567 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1568 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1569 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1570 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1571 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1574 if (dst_tex
) IDirect3DTexture_Release(dst_tex
);
1575 if (src_tex
) IDirect3DTexture_Release(src_tex
);
1576 if (dst
) IDirectDrawSurface_Release(dst
);
1577 if (src
) IDirectDrawSurface_Release(src
);
1578 if (ddraw
) IDirectDraw2_Release(ddraw
);
1581 static BOOL
compare_mode_rect(const DEVMODEW
*mode1
, const DEVMODEW
*mode2
)
1583 return mode1
->dmPosition
.x
== mode2
->dmPosition
.x
1584 && mode1
->dmPosition
.y
== mode2
->dmPosition
.y
1585 && mode1
->dmPelsWidth
== mode2
->dmPelsWidth
1586 && mode1
->dmPelsHeight
== mode2
->dmPelsHeight
;
1589 static ULONG
get_refcount(IUnknown
*test_iface
)
1591 IUnknown_AddRef(test_iface
);
1592 return IUnknown_Release(test_iface
);
1595 static void test_viewport_object(void)
1597 IDirectDraw2
*ddraw
;
1600 ULONG ref
, old_d3d_ref
;
1603 IDirect3DViewport
*viewport
;
1604 IDirect3DViewport2
*viewport2
, *another_vp
, *test_vp
;
1605 IDirect3DViewport3
*viewport3
;
1606 IDirectDrawGammaControl
*gamma
;
1608 IDirect3DDevice2
*device
;
1617 window
= create_window();
1618 ddraw
= create_ddraw();
1619 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1620 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1622 skip("Failed to create a 3D device, skipping test.\n");
1623 IDirectDraw2_Release(ddraw
);
1624 DestroyWindow(window
);
1628 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
1629 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get d3d interface, hr %#x.\n", hr
);
1632 skip("D3D interface is not available, skipping test.\n");
1633 IDirectDraw2_Release(ddraw
);
1636 old_d3d_ref
= get_refcount((IUnknown
*)d3d
);
1638 hr
= IDirect3D2_CreateViewport(d3d
, &viewport2
, NULL
);
1639 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1640 ref
= get_refcount((IUnknown
*)viewport2
);
1641 ok(ref
== 1, "Got unexpected refcount %u.\n", ref
);
1642 ref
= get_refcount((IUnknown
*)d3d
);
1643 ok(ref
== old_d3d_ref
, "Got unexpected refcount %u.\n", ref
);
1645 memset(&desc
, 0, sizeof(desc
));
1646 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1647 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1648 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) + 1;
1649 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1650 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1651 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) - 1;
1652 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1653 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1654 desc
.vp1
.dwSize
= sizeof(desc
.vp1
);
1655 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1656 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#x.\n", hr
);
1657 ok(desc
.vp1
.dwSize
== sizeof(desc
.vp1
), "Got unexpected dwSize %u.\n", desc
.vp1
.dwSize
);
1658 hr
= IDirect3DViewport2_GetViewport2(viewport2
, &desc
.vp2
);
1659 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#x.\n", hr
);
1660 ok(desc
.vp2
.dwSize
== sizeof(desc
.vp2
), "Got unexpected dwSize %u.\n", desc
.vp2
.dwSize
);
1661 desc
.vp2
.dwSize
= sizeof(desc
.vp2
) + 1;
1662 hr
= IDirect3DViewport2_GetViewport2(viewport2
, &desc
.vp2
);
1663 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1665 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1666 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1667 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
1668 ok(!gamma
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1669 /* NULL iid: Segfaults */
1671 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport
, (void **)&viewport
);
1672 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport, hr %#x.\n", hr
);
1673 ref
= get_refcount((IUnknown
*)viewport
);
1674 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1675 ref
= get_refcount((IUnknown
*)viewport2
);
1676 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1677 IDirect3DViewport_Release(viewport
);
1680 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport3
, (void **)&viewport3
);
1681 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to QI IDirect3DViewport3, hr %#x.\n", hr
);
1684 ref
= get_refcount((IUnknown
*)viewport2
);
1685 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1686 ref
= get_refcount((IUnknown
*)viewport3
);
1687 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1688 IDirect3DViewport3_Release(viewport3
);
1691 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IUnknown
, (void **)&unknown
);
1692 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#x.\n", hr
);
1693 ref
= get_refcount((IUnknown
*)viewport2
);
1694 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1695 ref
= get_refcount(unknown
);
1696 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1697 IUnknown_Release(unknown
);
1699 hr
= IDirect3DDevice2_DeleteViewport(device
, NULL
);
1700 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1701 hr
= IDirect3DDevice2_GetCurrentViewport(device
, NULL
);
1702 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1704 hr
= IDirect3D2_CreateViewport(d3d
, &another_vp
, NULL
);
1705 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1707 /* Setting a viewport not in the viewport list fails */
1708 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1709 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1711 /* AddViewport(NULL): Segfault */
1712 hr
= IDirect3DDevice2_AddViewport(device
, viewport2
);
1713 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1714 ref
= get_refcount((IUnknown
*) viewport2
);
1715 ok(ref
== 2, "viewport2 refcount is %u.\n", ref
);
1716 hr
= IDirect3DDevice2_AddViewport(device
, another_vp
);
1717 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1718 ref
= get_refcount((IUnknown
*) another_vp
);
1719 ok(ref
== 2, "another_vp refcount is %u.\n", ref
);
1721 test_vp
= (IDirect3DViewport2
*) 0xbaadc0de;
1722 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1723 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1724 ok(test_vp
== (IDirect3DViewport2
*) 0xbaadc0de, "Got unexpected pointer %p\n", test_vp
);
1726 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1727 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1728 ref
= get_refcount((IUnknown
*) viewport2
);
1729 ok(ref
== 3, "Got unexpected refcount %u.\n", ref
);
1730 ref
= get_refcount((IUnknown
*) device
);
1731 ok(ref
== 1, "Got unexpected refcount %u.\n", ref
);
1734 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1735 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1736 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1737 ref
= get_refcount((IUnknown
*) viewport2
);
1738 ok(ref
== 4, "Got unexpected refcount %u.\n", ref
);
1740 IDirect3DViewport2_Release(test_vp
);
1742 /* GetCurrentViewport with a viewport set and NULL input param: Segfault */
1744 /* Cannot set the viewport to NULL */
1745 hr
= IDirect3DDevice2_SetCurrentViewport(device
, NULL
);
1746 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to set viewport to NULL, hr %#x.\n", hr
);
1748 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1749 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1750 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1752 IDirect3DViewport2_Release(test_vp
);
1754 /* SetCurrentViewport properly releases the old viewport's reference */
1755 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1756 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1757 ref
= get_refcount((IUnknown
*) viewport2
);
1758 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1759 ref
= get_refcount((IUnknown
*) another_vp
);
1760 ok(ref
== 3, "Got unexpected refcount %u.\n", ref
);
1762 /* Deleting the viewport removes the reference added by AddViewport, but not
1763 * the one added by SetCurrentViewport. */
1764 hr
= IDirect3DDevice2_DeleteViewport(device
, another_vp
);
1765 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#x.\n", hr
);
1766 ref
= get_refcount((IUnknown
*) another_vp
);
1767 todo_wine
ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1769 /* GetCurrentViewport fails though */
1771 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1772 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1773 ok(!test_vp
, "Got unexpected viewport %p\n", test_vp
);
1775 /* Setting a different viewport does not free the leaked reference. How
1776 * do I get rid of it? Leak the viewport for now. */
1777 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1778 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1779 ref
= get_refcount((IUnknown
*) viewport2
);
1780 ok(ref
== 3, "Got unexpected refcount %u.\n", ref
);
1781 ref
= get_refcount((IUnknown
*) another_vp
);
1782 todo_wine
ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1784 memset(&vp
, 0, sizeof(vp
));
1785 memset(&vp
, 0, sizeof(vp2
));
1786 vp
.dwX
= vp2
.dwX
= 0;
1787 vp
.dwY
= vp2
.dwY
= 0;
1788 vp
.dwWidth
= vp2
.dwWidth
= 640;
1789 vp
.dwHeight
= vp2
.dwHeight
= 480;
1790 vp
.dvMinZ
= vp2
.dvMinZ
= 0.0f
;
1791 vp
.dvMaxZ
= vp2
.dvMaxZ
= 1.0f
;
1792 vp
.dvScaleX
= vp
.dwWidth
/ 2.0f
;
1793 vp
.dvScaleY
= vp
.dwHeight
/ 2.0f
;
1796 vp2
.dvClipX
= -1.0f
;
1798 vp2
.dvClipWidth
= 2.0f
;
1799 vp2
.dvClipHeight
= 2.0f
;
1800 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1801 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1802 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1803 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1805 vp
.dwSize
= sizeof(vp
);
1806 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1807 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
1808 vp2
.dwSize
= sizeof(vp2
);
1809 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1810 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
1812 /* Destroying the device removes the viewport, but does not free the reference
1813 * added by SetCurrentViewport. */
1814 IDirect3DDevice2_Release(device
);
1815 ref
= get_refcount((IUnknown
*) viewport2
);
1816 todo_wine
ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1818 vp
.dwSize
= sizeof(vp
);
1819 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1820 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#x.\n", hr
);
1821 vp2
.dwSize
= sizeof(vp2
);
1822 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1823 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#x.\n", hr
);
1825 IDirect3DViewport2_Release(another_vp
);
1826 IDirect3DViewport2_Release(viewport2
);
1827 IDirect3D2_Release(d3d
);
1828 DestroyWindow(window
);
1829 IDirectDraw2_Release(ddraw
);
1832 static void test_zenable(void)
1834 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1835 static D3DTLVERTEX tquad
[] =
1837 {{ 0.0f
}, {480.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1838 {{ 0.0f
}, { 0.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1839 {{640.0f
}, {480.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1840 {{640.0f
}, { 0.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1842 IDirect3DMaterial2
*background
;
1843 IDirect3DViewport2
*viewport
;
1844 IDirect3DDevice2
*device
;
1845 IDirectDrawSurface
*rt
;
1846 IDirectDraw2
*ddraw
;
1853 window
= create_window();
1854 ddraw
= create_ddraw();
1855 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1856 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1858 skip("Failed to create a 3D device, skipping test.\n");
1859 IDirectDraw2_Release(ddraw
);
1860 DestroyWindow(window
);
1864 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1865 viewport
= create_viewport(device
, 0, 0, 640, 480);
1866 viewport_set_background(device
, viewport
, background
);
1867 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1868 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1870 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1871 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
1873 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1874 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1875 hr
= IDirect3DDevice2_BeginScene(device
);
1876 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1877 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, tquad
, 4, 0);
1878 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1879 hr
= IDirect3DDevice2_EndScene(device
);
1880 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1882 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1883 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1884 for (i
= 0; i
< 4; ++i
)
1886 for (j
= 0; j
< 4; ++j
)
1888 x
= 80 * ((2 * j
) + 1);
1889 y
= 60 * ((2 * i
) + 1);
1890 color
= get_surface_color(rt
, x
, y
);
1891 ok(compare_color(color
, 0x0000ff00, 1),
1892 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1895 IDirectDrawSurface_Release(rt
);
1897 destroy_viewport(device
, viewport
);
1898 destroy_material(background
);
1899 IDirect3DDevice2_Release(device
);
1900 IDirectDraw2_Release(ddraw
);
1901 DestroyWindow(window
);
1904 static void test_ck_rgba(void)
1906 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1907 static D3DTLVERTEX tquad
[] =
1909 {{ 0.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1910 {{ 0.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1911 {{640.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1912 {{640.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1913 {{ 0.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1914 {{ 0.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1915 {{640.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1916 {{640.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1920 D3DCOLOR fill_color
;
1923 D3DCOLOR result1
, result1_broken
;
1924 D3DCOLOR result2
, result2_broken
;
1928 /* r200 on Windows doesn't check the alpha component when applying the color
1929 * key, so the key matches on every texel. */
1930 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1931 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1932 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1933 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1934 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00ff0000, 0x00807f00, 0x000000ff},
1935 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000, 0x0000ff00, 0x000000ff},
1936 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00, 0x00807f00, 0x00807f00},
1937 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1940 D3DTEXTUREHANDLE texture_handle
;
1941 IDirect3DMaterial2
*background
;
1942 IDirectDrawSurface
*surface
;
1943 IDirect3DViewport2
*viewport
;
1944 IDirect3DTexture2
*texture
;
1945 DDSURFACEDESC surface_desc
;
1946 IDirect3DDevice2
*device
;
1947 IDirectDrawSurface
*rt
;
1948 IDirectDraw2
*ddraw
;
1955 window
= create_window();
1956 ddraw
= create_ddraw();
1957 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1958 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1960 skip("Failed to create a 3D device, skipping test.\n");
1961 IDirectDraw2_Release(ddraw
);
1962 DestroyWindow(window
);
1966 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1967 viewport
= create_viewport(device
, 0, 0, 640, 480);
1968 viewport_set_background(device
, viewport
, background
);
1969 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1970 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1972 memset(&surface_desc
, 0, sizeof(surface_desc
));
1973 surface_desc
.dwSize
= sizeof(surface_desc
);
1974 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1975 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1976 surface_desc
.dwWidth
= 256;
1977 surface_desc
.dwHeight
= 256;
1978 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1979 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1980 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1981 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1982 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1983 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1984 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1985 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1986 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1987 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1988 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1989 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1990 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1991 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
1992 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1993 IDirect3DTexture2_Release(texture
);
1995 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1996 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1997 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1998 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1999 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2000 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
2002 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
2003 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
2005 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
2007 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
2008 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
2009 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
2010 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
2012 memset(&fx
, 0, sizeof(fx
));
2013 fx
.dwSize
= sizeof(fx
);
2014 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
2015 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2016 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
2018 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
2019 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
2020 hr
= IDirect3DDevice2_BeginScene(device
);
2021 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2022 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
2023 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2024 hr
= IDirect3DDevice2_EndScene(device
);
2025 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2027 color
= get_surface_color(rt
, 320, 240);
2028 ok(compare_color(color
, tests
[i
].result1
, 1) || compare_color(color
, tests
[i
].result1_broken
, 1),
2029 "Expected color 0x%08x for test %u, got 0x%08x.\n",
2030 tests
[i
].result1
, i
, color
);
2032 U5(fx
).dwFillColor
= 0xff0000ff;
2033 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2034 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
2036 hr
= IDirect3DDevice2_BeginScene(device
);
2037 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2038 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[4], 4, 0);
2039 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2040 hr
= IDirect3DDevice2_EndScene(device
);
2041 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2043 /* This tests that fragments that are masked out by the color key are
2044 * discarded, instead of just fully transparent. */
2045 color
= get_surface_color(rt
, 320, 240);
2046 ok(compare_color(color
, tests
[i
].result2
, 1) || compare_color(color
, tests
[i
].result2_broken
, 1),
2047 "Expected color 0x%08x for test %u, got 0x%08x.\n",
2048 tests
[i
].result2
, i
, color
);
2051 IDirectDrawSurface_Release(rt
);
2052 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
2053 ok(SUCCEEDED(hr
), "Failed to unset texture, hr %#x.\n", hr
);
2054 IDirectDrawSurface_Release(surface
);
2055 destroy_viewport(device
, viewport
);
2056 destroy_material(background
);
2057 IDirect3DDevice2_Release(device
);
2058 IDirectDraw2_Release(ddraw
);
2059 DestroyWindow(window
);
2062 static void test_ck_default(void)
2064 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
2065 static D3DTLVERTEX tquad
[] =
2067 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
2068 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
2069 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
2070 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
2072 IDirectDrawSurface
*surface
, *rt
;
2073 D3DTEXTUREHANDLE texture_handle
;
2074 IDirect3DMaterial2
*background
;
2075 IDirect3DViewport2
*viewport
;
2076 DDSURFACEDESC surface_desc
;
2077 IDirect3DTexture2
*texture
;
2078 IDirect3DDevice2
*device
;
2079 IDirectDraw2
*ddraw
;
2086 window
= create_window();
2087 ddraw
= create_ddraw();
2088 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2089 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2091 skip("Failed to create a 3D device, skipping test.\n");
2092 IDirectDraw2_Release(ddraw
);
2093 DestroyWindow(window
);
2097 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
2098 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
2100 background
= create_diffuse_material(device
, 0.0, 1.0f
, 0.0f
, 1.0f
);
2101 viewport
= create_viewport(device
, 0, 0, 640, 480);
2102 viewport_set_background(device
, viewport
, background
);
2103 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
2104 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
2106 memset(&surface_desc
, 0, sizeof(surface_desc
));
2107 surface_desc
.dwSize
= sizeof(surface_desc
);
2108 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
2109 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2110 surface_desc
.dwWidth
= 256;
2111 surface_desc
.dwHeight
= 256;
2112 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
2113 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
2114 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
2115 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
2116 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
2117 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
2118 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
2119 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
2120 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2121 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2122 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
2123 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
2124 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
2125 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
2126 IDirect3DTexture_Release(texture
);
2128 memset(&fx
, 0, sizeof(fx
));
2129 fx
.dwSize
= sizeof(fx
);
2130 U5(fx
).dwFillColor
= 0x000000ff;
2131 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2132 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
2134 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2135 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
2136 hr
= IDirect3DDevice2_BeginScene(device
);
2137 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2138 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
2139 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
2140 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
2141 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
2142 ok(!value
, "Got unexpected color keying state %#x.\n", value
);
2143 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
2144 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2145 hr
= IDirect3DDevice2_EndScene(device
);
2146 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2147 color
= get_surface_color(rt
, 320, 240);
2148 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
2150 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2151 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
2152 hr
= IDirect3DDevice2_BeginScene(device
);
2153 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2154 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
2155 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
2156 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
2157 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2158 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
2159 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
2160 ok(!!value
, "Got unexpected color keying state %#x.\n", value
);
2161 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
2162 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
2163 hr
= IDirect3DDevice2_EndScene(device
);
2164 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2165 color
= get_surface_color(rt
, 320, 240);
2166 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
2168 IDirectDrawSurface_Release(surface
);
2169 destroy_viewport(device
, viewport
);
2170 destroy_material(background
);
2171 IDirectDrawSurface_Release(rt
);
2172 IDirect3DDevice2_Release(device
);
2173 IDirectDraw2_Release(ddraw
);
2174 DestroyWindow(window
);
2177 static void test_ck_complex(void)
2179 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
2180 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
2181 DDSURFACEDESC surface_desc
;
2182 IDirect3DDevice2
*device
;
2183 DDCOLORKEY color_key
;
2184 IDirectDraw2
*ddraw
;
2190 window
= create_window();
2191 ddraw
= create_ddraw();
2192 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2193 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
2195 skip("Failed to create a 3D device, skipping test.\n");
2196 DestroyWindow(window
);
2197 IDirectDraw2_Release(ddraw
);
2200 IDirect3DDevice2_Release(device
);
2202 memset(&surface_desc
, 0, sizeof(surface_desc
));
2203 surface_desc
.dwSize
= sizeof(surface_desc
);
2204 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2205 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
2206 surface_desc
.dwWidth
= 128;
2207 surface_desc
.dwHeight
= 128;
2208 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2209 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2211 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2212 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2213 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2214 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2215 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2216 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2217 memset(&color_key
, 0, sizeof(color_key
));
2218 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2219 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2220 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2221 color_key
.dwColorSpaceLowValue
);
2222 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2223 color_key
.dwColorSpaceHighValue
);
2226 IDirectDrawSurface_AddRef(mipmap
);
2227 for (i
= 0; i
< 7; ++i
)
2229 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2230 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
2232 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2233 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2234 color_key
.dwColorSpaceLowValue
= 0x000000ff;
2235 color_key
.dwColorSpaceHighValue
= 0x000000ff;
2236 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2237 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x, i %u.\n", hr
, i
);
2238 memset(&color_key
, 0, sizeof(color_key
));
2239 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2240 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x, i %u.\n", hr
, i
);
2241 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
2242 color_key
.dwColorSpaceLowValue
, i
);
2243 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
2244 color_key
.dwColorSpaceHighValue
, i
);
2246 IDirectDrawSurface_Release(mipmap
);
2250 memset(&color_key
, 0, sizeof(color_key
));
2251 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2252 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2253 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2254 color_key
.dwColorSpaceLowValue
);
2255 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2256 color_key
.dwColorSpaceHighValue
);
2258 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2259 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
2260 IDirectDrawSurface_Release(mipmap
);
2261 refcount
= IDirectDrawSurface_Release(surface
);
2262 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2264 memset(&surface_desc
, 0, sizeof(surface_desc
));
2265 surface_desc
.dwSize
= sizeof(surface_desc
);
2266 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
2267 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
2268 surface_desc
.dwBackBufferCount
= 1;
2269 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2270 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2272 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2273 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2274 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2275 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2276 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2277 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2278 memset(&color_key
, 0, sizeof(color_key
));
2279 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2280 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2281 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2282 color_key
.dwColorSpaceLowValue
);
2283 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2284 color_key
.dwColorSpaceHighValue
);
2286 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
2287 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
2289 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2290 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2291 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2292 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2293 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2294 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2295 memset(&color_key
, 0, sizeof(color_key
));
2296 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2297 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2298 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2299 color_key
.dwColorSpaceLowValue
);
2300 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2301 color_key
.dwColorSpaceHighValue
);
2303 IDirectDrawSurface_Release(tmp
);
2305 refcount
= IDirectDrawSurface_Release(surface
);
2306 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2307 refcount
= IDirectDraw2_Release(ddraw
);
2308 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2309 DestroyWindow(window
);
2315 REFIID refcount_iid
;
2319 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
2320 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
2322 ULONG refcount
, expected_refcount
;
2323 IUnknown
*iface1
, *iface2
;
2327 for (i
= 0; i
< entry_count
; ++i
)
2329 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
2330 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
2333 for (j
= 0; j
< entry_count
; ++j
)
2335 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
2336 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
2339 expected_refcount
= 0;
2340 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
2341 ++expected_refcount
;
2342 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
2343 ++expected_refcount
;
2344 refcount
= IUnknown_Release(iface2
);
2345 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
2346 refcount
, test_name
, i
, j
, expected_refcount
);
2350 expected_refcount
= 0;
2351 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
2352 ++expected_refcount
;
2353 refcount
= IUnknown_Release(iface1
);
2354 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
2355 refcount
, test_name
, i
, expected_refcount
);
2360 static void test_surface_qi(void)
2362 static const struct qi_test tests
[] =
2364 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
2365 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
2366 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2367 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2368 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2369 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2370 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2371 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2372 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2373 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2374 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2375 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2376 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2377 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2378 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2379 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2380 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2381 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2382 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2383 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2384 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2385 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2386 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2387 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2388 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2389 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2390 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2391 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2392 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2393 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2394 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2395 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2396 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2397 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2398 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2399 {NULL
, NULL
, E_INVALIDARG
},
2402 IDirectDrawSurface
*surface
;
2403 DDSURFACEDESC surface_desc
;
2404 IDirect3DDevice2
*device
;
2405 IDirectDraw2
*ddraw
;
2409 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2411 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2415 window
= create_window();
2416 ddraw
= create_ddraw();
2417 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2418 /* Try to create a D3D device to see if the ddraw implementation supports
2419 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
2420 * doesn't support e.g. the IDirect3DTexture interfaces. */
2421 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2423 skip("Failed to create a 3D device, skipping test.\n");
2424 IDirectDraw2_Release(ddraw
);
2425 DestroyWindow(window
);
2428 IDirect3DDevice_Release(device
);
2430 memset(&surface_desc
, 0, sizeof(surface_desc
));
2431 surface_desc
.dwSize
= sizeof(surface_desc
);
2432 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2433 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2434 surface_desc
.dwWidth
= 512;
2435 surface_desc
.dwHeight
= 512;
2436 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, (IDirectDrawSurface
**)0xdeadbeef, NULL
);
2437 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
2438 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2439 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2441 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface
, tests
, ARRAY_SIZE(tests
));
2443 IDirectDrawSurface_Release(surface
);
2444 IDirectDraw2_Release(ddraw
);
2445 DestroyWindow(window
);
2448 static void test_device_qi(void)
2450 static const struct qi_test tests
[] =
2452 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
2453 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
2454 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
2455 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2456 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
2457 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
2458 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
2459 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
2460 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
2461 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
2462 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
2463 {&IID_IDirect3DDevice2
, &IID_IDirect3DDevice2
, S_OK
},
2464 {&IID_IDirect3DDevice
, &IID_IDirect3DDevice2
, S_OK
},
2465 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
2466 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
2467 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
2468 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
2469 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
2470 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
2471 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
2472 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
2473 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
2474 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
2475 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
2476 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
2477 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
2478 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
2479 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
2480 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
2481 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
2482 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
2483 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
2484 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
2485 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
2486 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
2487 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
2488 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
2489 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
2490 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
2491 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
2492 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
2493 {&IID_IUnknown
, &IID_IDirect3DDevice2
, S_OK
},
2496 IDirect3DDevice2
*device
;
2497 IDirectDraw2
*ddraw
;
2500 window
= create_window();
2501 ddraw
= create_ddraw();
2502 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2503 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2505 skip("Failed to create a 3D device, skipping test.\n");
2506 IDirectDraw2_Release(ddraw
);
2507 DestroyWindow(window
);
2511 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice2
, tests
, ARRAY_SIZE(tests
));
2513 IDirect3DDevice2_Release(device
);
2514 IDirectDraw2_Release(ddraw
);
2515 DestroyWindow(window
);
2518 static void test_wndproc(void)
2520 LONG_PTR proc
, ddraw_proc
;
2521 IDirectDraw2
*ddraw
;
2527 static struct message messages
[] =
2529 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2530 {WM_MOVE
, FALSE
, 0},
2531 {WM_SIZE
, FALSE
, 0},
2532 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2533 {WM_ACTIVATE
, FALSE
, 0},
2534 {WM_SETFOCUS
, FALSE
, 0},
2538 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2539 ddraw
= create_ddraw();
2540 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2542 wc
.lpfnWndProc
= test_proc
;
2543 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2544 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2546 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2547 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2549 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2550 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2551 (LONG_PTR
)test_proc
, proc
);
2552 expect_messages
= messages
;
2553 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2554 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2555 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2556 expect_messages
= NULL
;
2557 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2558 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2559 (LONG_PTR
)test_proc
, proc
);
2560 ref
= IDirectDraw2_Release(ddraw
);
2561 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2562 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2563 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2564 (LONG_PTR
)test_proc
, proc
);
2566 /* DDSCL_NORMAL doesn't. */
2567 ddraw
= create_ddraw();
2568 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2569 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2570 (LONG_PTR
)test_proc
, proc
);
2571 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2572 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2573 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2574 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2575 (LONG_PTR
)test_proc
, proc
);
2576 ref
= IDirectDraw2_Release(ddraw
);
2577 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2578 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2579 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2580 (LONG_PTR
)test_proc
, proc
);
2582 /* The original window proc is only restored by ddraw if the current
2583 * window proc matches the one ddraw set. This also affects switching
2584 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2585 ddraw
= create_ddraw();
2586 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2587 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2588 (LONG_PTR
)test_proc
, proc
);
2589 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2590 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2591 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2592 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2593 (LONG_PTR
)test_proc
, proc
);
2595 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2596 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2597 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2598 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2599 (LONG_PTR
)test_proc
, proc
);
2600 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2601 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2602 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2603 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2604 (LONG_PTR
)test_proc
, proc
);
2605 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2606 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2607 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2608 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2609 (LONG_PTR
)DefWindowProcA
, proc
);
2610 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2611 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2612 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, ddraw_proc
);
2613 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2614 (LONG_PTR
)DefWindowProcA
, proc
);
2615 ref
= IDirectDraw2_Release(ddraw
);
2616 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2617 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2618 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2619 (LONG_PTR
)test_proc
, proc
);
2621 ddraw
= create_ddraw();
2622 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2623 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2624 (LONG_PTR
)test_proc
, proc
);
2625 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2626 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2627 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2628 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2629 (LONG_PTR
)test_proc
, proc
);
2630 ref
= IDirectDraw2_Release(ddraw
);
2631 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2632 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2633 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2634 (LONG_PTR
)DefWindowProcA
, proc
);
2636 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2637 expect_messages
= NULL
;
2638 DestroyWindow(window
);
2639 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2642 static void test_window_style(void)
2644 LONG style
, exstyle
, tmp
, expected_style
;
2645 RECT fullscreen_rect
, r
;
2646 IDirectDraw2
*ddraw
;
2652 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2653 0, 0, 100, 100, 0, 0, 0, 0);
2654 ddraw
= create_ddraw();
2655 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2657 style
= GetWindowLongA(window
, GWL_STYLE
);
2658 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2659 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2661 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2662 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2664 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2665 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2666 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2667 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2669 GetWindowRect(window
, &r
);
2670 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2671 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2672 GetClientRect(window
, &r
);
2673 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2675 ret
= SetForegroundWindow(GetDesktopWindow());
2676 ok(ret
, "Failed to set foreground window.\n");
2678 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2679 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2680 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2681 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2683 ret
= SetForegroundWindow(window
);
2684 ok(ret
, "Failed to set foreground window.\n");
2685 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2686 * the next tests expect this. */
2687 ShowWindow(window
, SW_HIDE
);
2689 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2690 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2692 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2693 ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2694 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2695 ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2697 ShowWindow(window
, SW_SHOW
);
2698 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2699 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2701 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2702 expected_style
= style
| WS_VISIBLE
;
2703 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2704 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2705 expected_style
= exstyle
| WS_EX_TOPMOST
;
2706 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2708 ret
= SetForegroundWindow(GetDesktopWindow());
2709 ok(ret
, "Failed to set foreground window.\n");
2710 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2711 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
2712 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2713 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2714 expected_style
= exstyle
| WS_EX_TOPMOST
;
2715 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2717 ref
= IDirectDraw2_Release(ddraw
);
2718 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2720 DestroyWindow(window
);
2723 static void test_redundant_mode_set(void)
2725 DDSURFACEDESC surface_desc
= {0};
2726 IDirectDraw2
*ddraw
;
2732 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2733 0, 0, 100, 100, 0, 0, 0, 0);
2734 ddraw
= create_ddraw();
2735 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2737 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2738 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2740 surface_desc
.dwSize
= sizeof(surface_desc
);
2741 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
2742 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
2744 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2745 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2746 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2748 GetWindowRect(window
, &q
);
2752 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2753 GetWindowRect(window
, &s
);
2754 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2756 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2757 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2758 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2760 GetWindowRect(window
, &s
);
2761 ok(EqualRect(&r
, &s
) || broken(EqualRect(&q
, &s
) /* Windows 10 */),
2762 "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2764 ref
= IDirectDraw2_Release(ddraw
);
2765 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2767 DestroyWindow(window
);
2770 static SIZE screen_size
, screen_size2
;
2772 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2774 if (message
== WM_SIZE
)
2776 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2777 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2780 return test_proc(hwnd
, message
, wparam
, lparam
);
2783 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2785 if (message
== WM_SIZE
)
2787 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2788 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2791 return test_proc(hwnd
, message
, wparam
, lparam
);
2794 struct test_coop_level_mode_set_enum_param
2796 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
2799 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC
*surface_desc
, void *context
)
2801 struct test_coop_level_mode_set_enum_param
*param
= context
;
2803 if (U1(surface_desc
->ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
2804 return DDENUMRET_OK
;
2805 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
2806 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
2807 return DDENUMRET_OK
;
2809 if (!param
->ddraw_width
)
2811 param
->ddraw_width
= surface_desc
->dwWidth
;
2812 param
->ddraw_height
= surface_desc
->dwHeight
;
2813 return DDENUMRET_OK
;
2815 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
2816 return DDENUMRET_OK
;
2818 param
->user32_width
= surface_desc
->dwWidth
;
2819 param
->user32_height
= surface_desc
->dwHeight
;
2820 return DDENUMRET_CANCEL
;
2823 static void test_coop_level_mode_set(void)
2825 DEVMODEW
*original_modes
= NULL
, devmode
, devmode2
;
2826 unsigned int display_count
= 0;
2827 IDirectDrawSurface
*primary
;
2828 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
2829 IDirectDraw2
*ddraw
;
2832 HWND window
, window2
;
2836 struct test_coop_level_mode_set_enum_param param
;
2840 static const struct message exclusive_messages
[] =
2842 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2843 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2844 {WM_SIZE
, FALSE
, 0},
2845 {WM_DISPLAYCHANGE
, FALSE
, 0},
2848 static const struct message exclusive_focus_loss_messages
[] =
2850 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
},
2851 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Window resize due to mode change. */
2852 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2853 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* Generated by DefWindowProc. */
2854 {WM_DISPLAYCHANGE
, FALSE
, 0},
2855 {WM_KILLFOCUS
, FALSE
, 0},
2856 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Window minimized. */
2857 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
2858 * SW_MINIMIZED, causing a recursive window activation that does not
2859 * produce the same result in Wine yet. Ignore the difference for now.
2860 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
2861 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2862 {WM_MOVE
, FALSE
, 0},
2863 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2864 {WM_ACTIVATEAPP
, TRUE
, FALSE
},
2867 static const struct message exclusive_focus_restore_messages
[] =
2869 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
2870 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
2871 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
2872 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
2873 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
2874 /* Native redundantly sets the window size here. */
2875 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
2876 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
2877 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
2878 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
2881 static const struct message sc_restore_messages
[] =
2883 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
2884 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2885 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2886 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
2889 static const struct message sc_minimize_messages
[] =
2891 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
2892 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2893 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2894 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2897 static const struct message sc_maximize_messages
[] =
2899 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
2900 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2901 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2902 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
2906 static const struct message normal_messages
[] =
2908 {WM_DISPLAYCHANGE
, FALSE
, 0},
2912 memset(&devmode
, 0, sizeof(devmode
));
2913 devmode
.dmSize
= sizeof(devmode
);
2914 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2915 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
2916 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
2917 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
2918 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
2919 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
2921 ret
= save_display_modes(&original_modes
, &display_count
);
2922 ok(ret
, "Failed to save original display modes.\n");
2924 ddraw
= create_ddraw();
2925 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2927 memset(¶m
, 0, sizeof(param
));
2928 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
2929 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#x.\n", hr
);
2930 ref
= IDirectDraw2_Release(ddraw
);
2931 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2933 if (!param
.user32_height
)
2935 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
2936 heap_free(original_modes
);
2940 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2941 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
2942 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
2944 memset(&devmode
, 0, sizeof(devmode
));
2945 devmode
.dmSize
= sizeof(devmode
);
2946 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2947 devmode
.dmPelsWidth
= param
.user32_width
;
2948 devmode
.dmPelsHeight
= param
.user32_height
;
2949 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2950 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2952 ddraw
= create_ddraw();
2953 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2955 wc
.lpfnWndProc
= mode_set_proc
;
2956 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2957 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2958 wc
.lpfnWndProc
= mode_set_proc2
;
2959 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
2960 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2962 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2963 0, 0, 100, 100, 0, 0, 0, 0);
2964 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2965 0, 0, 100, 100, 0, 0, 0, 0);
2967 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2968 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2970 GetWindowRect(window
, &r
);
2971 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2972 wine_dbgstr_rect(&r
));
2974 memset(&ddsd
, 0, sizeof(ddsd
));
2975 ddsd
.dwSize
= sizeof(ddsd
);
2976 ddsd
.dwFlags
= DDSD_CAPS
;
2977 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2979 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2980 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2981 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2982 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2983 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2984 param
.user32_width
, ddsd
.dwWidth
);
2985 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2986 param
.user32_height
, ddsd
.dwHeight
);
2988 GetWindowRect(window
, &r
);
2989 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2990 wine_dbgstr_rect(&r
));
2992 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2993 expect_messages
= exclusive_messages
;
2997 hr
= IDirectDrawSurface_IsLost(primary
);
2998 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2999 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3000 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3001 hr
= IDirectDrawSurface_IsLost(primary
);
3002 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3004 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3005 expect_messages
= NULL
;
3006 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
3007 "Expected screen size %ux%u, got %ux%u.\n",
3008 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
3010 GetWindowRect(window
, &r
);
3011 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3012 wine_dbgstr_rect(&r
));
3014 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3015 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3016 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
3017 param
.user32_width
, ddsd
.dwWidth
);
3018 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
3019 param
.user32_height
, ddsd
.dwHeight
);
3020 IDirectDrawSurface_Release(primary
);
3022 memset(&ddsd
, 0, sizeof(ddsd
));
3023 ddsd
.dwSize
= sizeof(ddsd
);
3024 ddsd
.dwFlags
= DDSD_CAPS
;
3025 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3027 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3028 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3029 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3030 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3031 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3032 param
.ddraw_width
, ddsd
.dwWidth
);
3033 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3034 param
.ddraw_height
, ddsd
.dwHeight
);
3036 GetWindowRect(window
, &r
);
3037 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3038 wine_dbgstr_rect(&r
));
3040 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3041 expect_messages
= exclusive_messages
;
3045 hr
= IDirectDrawSurface_IsLost(primary
);
3046 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3047 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3048 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3049 hr
= IDirectDrawSurface_IsLost(primary
);
3050 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3052 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3053 expect_messages
= NULL
;
3054 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
3055 "Expected screen size %ux%u, got %ux%u.\n",
3056 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
3058 GetWindowRect(window
, &r
);
3059 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3060 wine_dbgstr_rect(&r
));
3062 expect_messages
= exclusive_focus_loss_messages
;
3063 ret
= SetForegroundWindow(GetDesktopWindow());
3064 ok(ret
, "Failed to set foreground window.\n");
3065 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3066 memset(&devmode
, 0, sizeof(devmode
));
3067 devmode
.dmSize
= sizeof(devmode
);
3068 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3069 ok(ret
, "Failed to get display mode.\n");
3070 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3071 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpected screen size %ux%u.\n",
3072 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3074 expect_messages
= exclusive_focus_restore_messages
;
3075 ShowWindow(window
, SW_RESTORE
);
3076 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3078 GetWindowRect(window
, &r
);
3079 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3080 wine_dbgstr_rect(&r
));
3081 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3082 ok(ret
, "Failed to get display mode.\n");
3083 ok(devmode
.dmPelsWidth
== param
.ddraw_width
3084 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpected screen size %ux%u.\n",
3085 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3087 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3088 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3089 /* Normally the primary should be restored here. Unfortunately this causes the
3090 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
3091 * testbot. Another Restore call would presumably avoid the crash, but it also moots
3092 * the point of the GetSurfaceDesc call. */
3094 expect_messages
= sc_minimize_messages
;
3095 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
3096 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3097 expect_messages
= NULL
;
3099 expect_messages
= sc_restore_messages
;
3100 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
3101 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3102 expect_messages
= NULL
;
3104 expect_messages
= sc_maximize_messages
;
3105 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
3106 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3107 expect_messages
= NULL
;
3109 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3110 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3112 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3113 expect_messages
= exclusive_messages
;
3117 hr
= IDirectDrawSurface_IsLost(primary
);
3118 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3119 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3120 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3121 hr
= IDirectDrawSurface_IsLost(primary
);
3122 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3124 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3125 expect_messages
= NULL
;
3126 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3127 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3128 "Expected screen size %ux%u, got %ux%u.\n",
3129 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
3131 GetWindowRect(window
, &r
);
3132 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3133 wine_dbgstr_rect(&r
));
3135 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3136 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3137 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3138 param
.ddraw_width
, ddsd
.dwWidth
);
3139 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3140 param
.ddraw_height
, ddsd
.dwHeight
);
3141 IDirectDrawSurface_Release(primary
);
3144 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3145 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3147 memset(&ddsd
, 0, sizeof(ddsd
));
3148 ddsd
.dwSize
= sizeof(ddsd
);
3149 ddsd
.dwFlags
= DDSD_CAPS
;
3150 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3152 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3153 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3154 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3155 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3156 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3157 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3158 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3159 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3161 GetWindowRect(window
, &r
);
3162 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3163 wine_dbgstr_rect(&r
));
3165 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3166 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3168 GetWindowRect(window
, &r
);
3169 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3170 wine_dbgstr_rect(&r
));
3172 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3173 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3174 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3175 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3176 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3177 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3178 IDirectDrawSurface_Release(primary
);
3180 memset(&ddsd
, 0, sizeof(ddsd
));
3181 ddsd
.dwSize
= sizeof(ddsd
);
3182 ddsd
.dwFlags
= DDSD_CAPS
;
3183 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3185 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3186 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3187 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3188 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3189 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3190 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3191 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3192 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3194 GetWindowRect(window
, &r
);
3195 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3196 wine_dbgstr_rect(&r
));
3198 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3199 expect_messages
= normal_messages
;
3203 hr
= IDirectDrawSurface_IsLost(primary
);
3204 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3205 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3206 devmode
.dmPelsWidth
= param
.user32_width
;
3207 devmode
.dmPelsHeight
= param
.user32_height
;
3208 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3209 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3210 hr
= IDirectDrawSurface_IsLost(primary
);
3211 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3213 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3214 expect_messages
= NULL
;
3215 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3217 GetWindowRect(window
, &r
);
3218 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3219 wine_dbgstr_rect(&r
));
3221 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3222 expect_messages
= normal_messages
;
3226 hr
= IDirectDrawSurface_Restore(primary
);
3227 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3228 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3229 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3231 win_skip("Broken SetDisplayMode(), skipping remaining tests.\n");
3232 IDirectDrawSurface_Release(primary
);
3233 IDirectDraw2_Release(ddraw
);
3236 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3237 hr
= IDirectDrawSurface_Restore(primary
);
3238 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3239 hr
= IDirectDrawSurface_IsLost(primary
);
3240 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3242 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3243 expect_messages
= NULL
;
3244 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3246 GetWindowRect(window
, &r
);
3247 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3248 wine_dbgstr_rect(&r
));
3250 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3251 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3252 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3253 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3254 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3255 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3256 IDirectDrawSurface_Release(primary
);
3258 memset(&ddsd
, 0, sizeof(ddsd
));
3259 ddsd
.dwSize
= sizeof(ddsd
);
3260 ddsd
.dwFlags
= DDSD_CAPS
;
3261 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3263 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3264 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3265 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3266 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3267 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3268 param
.ddraw_width
, ddsd
.dwWidth
);
3269 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3270 param
.ddraw_height
, ddsd
.dwHeight
);
3272 GetWindowRect(window
, &r
);
3273 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3274 wine_dbgstr_rect(&r
));
3276 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3277 expect_messages
= normal_messages
;
3281 hr
= IDirectDrawSurface_IsLost(primary
);
3282 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3283 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3284 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3285 hr
= IDirectDrawSurface_IsLost(primary
);
3286 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3288 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3289 expect_messages
= NULL
;
3290 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3292 GetWindowRect(window
, &r
);
3293 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3294 wine_dbgstr_rect(&r
));
3296 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3297 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3298 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3299 param
.ddraw_width
, ddsd
.dwWidth
);
3300 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3301 param
.ddraw_height
, ddsd
.dwHeight
);
3302 IDirectDrawSurface_Release(primary
);
3304 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3305 ok(ret
, "Failed to get display mode.\n");
3306 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3307 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3308 "Expected resolution %ux%u, got %ux%u.\n",
3309 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3310 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3311 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3312 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3314 memset(&ddsd
, 0, sizeof(ddsd
));
3315 ddsd
.dwSize
= sizeof(ddsd
);
3316 ddsd
.dwFlags
= DDSD_CAPS
;
3317 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3319 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3320 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3321 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3322 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3323 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3324 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3325 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3326 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3328 GetWindowRect(window
, &r
);
3329 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3330 wine_dbgstr_rect(&r
));
3332 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3333 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3334 * not DDSCL_FULLSCREEN. */
3335 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3336 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3338 GetWindowRect(window
, &r
);
3339 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3340 wine_dbgstr_rect(&r
));
3342 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3343 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3344 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3345 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3346 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3347 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3348 IDirectDrawSurface_Release(primary
);
3350 memset(&ddsd
, 0, sizeof(ddsd
));
3351 ddsd
.dwSize
= sizeof(ddsd
);
3352 ddsd
.dwFlags
= DDSD_CAPS
;
3353 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3355 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3356 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3357 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3358 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3359 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3360 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3361 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3362 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3364 GetWindowRect(window
, &r
);
3365 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3366 wine_dbgstr_rect(&r
));
3368 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3369 expect_messages
= normal_messages
;
3373 hr
= IDirectDrawSurface_IsLost(primary
);
3374 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3375 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3376 devmode
.dmPelsWidth
= param
.user32_width
;
3377 devmode
.dmPelsHeight
= param
.user32_height
;
3378 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3379 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3380 hr
= IDirectDrawSurface_IsLost(primary
);
3381 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3383 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3384 expect_messages
= NULL
;
3385 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3387 GetWindowRect(window
, &r
);
3388 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3389 wine_dbgstr_rect(&r
));
3391 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3392 expect_messages
= normal_messages
;
3396 hr
= IDirectDrawSurface_Restore(primary
);
3397 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3398 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3399 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3400 hr
= IDirectDrawSurface_Restore(primary
);
3401 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3402 hr
= IDirectDrawSurface_IsLost(primary
);
3403 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3405 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3406 expect_messages
= NULL
;
3407 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3409 GetWindowRect(window
, &r
);
3410 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3411 wine_dbgstr_rect(&r
));
3413 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3414 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3415 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3416 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3417 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3418 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3419 IDirectDrawSurface_Release(primary
);
3421 memset(&ddsd
, 0, sizeof(ddsd
));
3422 ddsd
.dwSize
= sizeof(ddsd
);
3423 ddsd
.dwFlags
= DDSD_CAPS
;
3424 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3426 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3427 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3428 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3429 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3430 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3431 param
.ddraw_width
, ddsd
.dwWidth
);
3432 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3433 param
.ddraw_height
, ddsd
.dwHeight
);
3435 GetWindowRect(window
, &r
);
3436 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3437 wine_dbgstr_rect(&r
));
3439 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3440 expect_messages
= normal_messages
;
3444 hr
= IDirectDrawSurface_IsLost(primary
);
3445 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3446 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3447 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3448 hr
= IDirectDrawSurface_IsLost(primary
);
3449 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3451 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3452 expect_messages
= NULL
;
3453 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3455 GetWindowRect(window
, &r
);
3456 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3457 wine_dbgstr_rect(&r
));
3459 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3460 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3461 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3462 param
.ddraw_width
, ddsd
.dwWidth
);
3463 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3464 param
.ddraw_height
, ddsd
.dwHeight
);
3465 IDirectDrawSurface_Release(primary
);
3467 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3468 ok(ret
, "Failed to get display mode.\n");
3469 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3470 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3471 "Expected resolution %ux%u, got %ux%u.\n",
3472 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3473 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3474 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3475 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3477 memset(&ddsd
, 0, sizeof(ddsd
));
3478 ddsd
.dwSize
= sizeof(ddsd
);
3479 ddsd
.dwFlags
= DDSD_CAPS
;
3480 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3482 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3483 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3484 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3485 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3486 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3487 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3488 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3489 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3490 IDirectDrawSurface_Release(primary
);
3492 GetWindowRect(window
, &r
);
3493 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3494 wine_dbgstr_rect(&r
));
3496 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
3497 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3498 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3499 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3500 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3502 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3503 expect_messages
= exclusive_messages
;
3507 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3508 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3510 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3511 expect_messages
= NULL
;
3512 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3513 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3514 "Expected screen size %ux%u, got %ux%u.\n",
3515 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3516 screen_size
.cx
, screen_size
.cy
);
3518 GetWindowRect(window
, &r
);
3519 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3520 wine_dbgstr_rect(&r
));
3522 memset(&ddsd
, 0, sizeof(ddsd
));
3523 ddsd
.dwSize
= sizeof(ddsd
);
3524 ddsd
.dwFlags
= DDSD_CAPS
;
3525 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3527 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3528 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3529 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3530 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3531 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3532 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3533 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3534 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3535 IDirectDrawSurface_Release(primary
);
3537 /* The screen restore is a property of DDSCL_EXCLUSIVE */
3538 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3539 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3540 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3541 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3543 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3544 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3546 memset(&ddsd
, 0, sizeof(ddsd
));
3547 ddsd
.dwSize
= sizeof(ddsd
);
3548 ddsd
.dwFlags
= DDSD_CAPS
;
3549 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3551 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3552 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3553 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3554 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3555 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3556 param
.ddraw_width
, ddsd
.dwWidth
);
3557 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3558 param
.ddraw_height
, ddsd
.dwHeight
);
3559 IDirectDrawSurface_Release(primary
);
3561 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3562 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3564 /* If the window is changed at the same time, messages are sent to the new window. */
3565 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3566 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3567 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3568 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3570 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3571 expect_messages
= exclusive_messages
;
3574 screen_size2
.cx
= 0;
3575 screen_size2
.cy
= 0;
3577 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3578 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3580 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3581 expect_messages
= NULL
;
3582 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n",
3583 screen_size
.cx
, screen_size
.cy
);
3584 ok(screen_size2
.cx
== registry_mode
.dmPelsWidth
&& screen_size2
.cy
== registry_mode
.dmPelsHeight
,
3585 "Expected screen size 2 %ux%u, got %ux%u.\n",
3586 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size2
.cx
, screen_size2
.cy
);
3588 GetWindowRect(window
, &r
);
3589 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3590 wine_dbgstr_rect(&r
));
3591 GetWindowRect(window2
, &r
);
3592 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3593 wine_dbgstr_rect(&r
));
3595 memset(&ddsd
, 0, sizeof(ddsd
));
3596 ddsd
.dwSize
= sizeof(ddsd
);
3597 ddsd
.dwFlags
= DDSD_CAPS
;
3598 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3600 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3601 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3602 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3603 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3604 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3605 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3606 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3607 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3608 IDirectDrawSurface_Release(primary
);
3610 ref
= IDirectDraw2_Release(ddraw
);
3611 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3613 GetWindowRect(window
, &r
);
3614 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3615 wine_dbgstr_rect(&r
));
3617 ret
= restore_display_modes(original_modes
, display_count
);
3618 ok(ret
, "Failed to restore display modes.\n");
3620 /* Test that no mode restorations if no mode changes happened */
3621 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3622 devmode
.dmPelsWidth
= param
.user32_width
;
3623 devmode
.dmPelsHeight
= param
.user32_height
;
3624 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3625 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %d.\n", change_ret
);
3627 ddraw
= create_ddraw();
3628 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3629 ref
= IDirectDraw2_Release(ddraw
);
3630 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3632 memset(&devmode2
, 0, sizeof(devmode2
));
3633 devmode2
.dmSize
= sizeof(devmode2
);
3634 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3635 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3636 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3637 ret
= restore_display_modes(original_modes
, display_count
);
3638 ok(ret
, "Failed to restore display modes.\n");
3640 /* Test that no mode restorations if no mode changes happened with fullscreen ddraw objects */
3641 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3642 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %d.\n", change_ret
);
3644 ddraw
= create_ddraw();
3645 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3646 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3647 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
3648 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3649 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
3650 ref
= IDirectDraw2_Release(ddraw
);
3651 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3653 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3654 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3655 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3656 ret
= restore_display_modes(original_modes
, display_count
);
3657 ok(ret
, "Failed to restore display modes.\n");
3659 /* Test that mode restorations use display settings in the registry after ddraw object releases
3660 * if SetDisplayMode() was called */
3661 ddraw
= create_ddraw();
3662 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3663 hr
= set_display_mode(ddraw
, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
3664 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
3666 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3667 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %d.\n", change_ret
);
3669 ref
= IDirectDraw2_Release(ddraw
);
3670 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3672 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3673 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3674 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3675 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3676 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3677 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3678 ret
= restore_display_modes(original_modes
, display_count
);
3679 ok(ret
, "Failed to restore display modes.\n");
3681 /* Test that mode restorations use display settings in the registry after RestoreDisplayMode() */
3682 ddraw
= create_ddraw();
3683 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3684 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3685 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
3687 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3688 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %d.\n", change_ret
);
3690 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3691 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
3693 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3694 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3695 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3696 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3697 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3698 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3700 ref
= IDirectDraw2_Release(ddraw
);
3701 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3704 expect_messages
= NULL
;
3705 DestroyWindow(window
);
3706 DestroyWindow(window2
);
3707 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3708 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
3709 ret
= restore_display_modes(original_modes
, display_count
);
3710 ok(ret
, "Failed to restore display modes.\n");
3711 heap_free(original_modes
);
3714 static void test_coop_level_mode_set_multi(void)
3716 DEVMODEW old_devmode
, devmode
, devmode2
, devmode3
, *original_modes
= NULL
;
3717 unsigned int mode_idx
= 0, display_idx
, display_count
= 0;
3718 WCHAR second_monitor_name
[CCHDEVICENAME
];
3719 IDirectDraw2
*ddraw1
, *ddraw2
;
3727 memset(&devmode
, 0, sizeof(devmode
));
3728 devmode
.dmSize
= sizeof(devmode
);
3729 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3730 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3731 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3732 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
3733 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3734 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3736 ret
= save_display_modes(&original_modes
, &display_count
);
3737 ok(ret
, "Failed to save original display modes.\n");
3739 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3740 0, 0, 100, 100, 0, 0, 0, 0);
3741 ddraw1
= create_ddraw();
3742 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3744 /* With just a single ddraw object, the display mode is restored on
3746 hr
= set_display_mode(ddraw1
, 800, 600);
3747 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3749 win_skip("Broken SetDisplayMode(), skipping test.\n");
3750 IDirectDraw2_Release(ddraw1
);
3751 DestroyWindow(window
);
3754 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3755 w
= GetSystemMetrics(SM_CXSCREEN
);
3756 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3757 h
= GetSystemMetrics(SM_CYSCREEN
);
3758 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3760 ref
= IDirectDraw2_Release(ddraw1
);
3761 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3762 w
= GetSystemMetrics(SM_CXSCREEN
);
3763 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3764 h
= GetSystemMetrics(SM_CYSCREEN
);
3765 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3767 /* When there are multiple ddraw objects, the display mode is restored to
3768 * the initial mode, before the first SetDisplayMode() call. */
3769 ddraw1
= create_ddraw();
3770 hr
= set_display_mode(ddraw1
, 800, 600);
3771 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3772 w
= GetSystemMetrics(SM_CXSCREEN
);
3773 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3774 h
= GetSystemMetrics(SM_CYSCREEN
);
3775 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3777 ddraw2
= create_ddraw();
3778 hr
= set_display_mode(ddraw2
, 640, 480);
3779 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3780 w
= GetSystemMetrics(SM_CXSCREEN
);
3781 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3782 h
= GetSystemMetrics(SM_CYSCREEN
);
3783 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3785 ref
= IDirectDraw2_Release(ddraw2
);
3786 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3787 w
= GetSystemMetrics(SM_CXSCREEN
);
3788 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3789 h
= GetSystemMetrics(SM_CYSCREEN
);
3790 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3792 ref
= IDirectDraw2_Release(ddraw1
);
3793 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3794 w
= GetSystemMetrics(SM_CXSCREEN
);
3795 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3796 h
= GetSystemMetrics(SM_CYSCREEN
);
3797 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3799 /* Regardless of release ordering. */
3800 ddraw1
= create_ddraw();
3801 hr
= set_display_mode(ddraw1
, 800, 600);
3802 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3803 w
= GetSystemMetrics(SM_CXSCREEN
);
3804 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3805 h
= GetSystemMetrics(SM_CYSCREEN
);
3806 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3808 ddraw2
= create_ddraw();
3809 hr
= set_display_mode(ddraw2
, 640, 480);
3810 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3811 w
= GetSystemMetrics(SM_CXSCREEN
);
3812 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3813 h
= GetSystemMetrics(SM_CYSCREEN
);
3814 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3816 ref
= IDirectDraw2_Release(ddraw1
);
3817 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3818 w
= GetSystemMetrics(SM_CXSCREEN
);
3819 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3820 h
= GetSystemMetrics(SM_CYSCREEN
);
3821 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3823 ref
= IDirectDraw2_Release(ddraw2
);
3824 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3825 w
= GetSystemMetrics(SM_CXSCREEN
);
3826 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3827 h
= GetSystemMetrics(SM_CYSCREEN
);
3828 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3830 /* But only for ddraw objects that called SetDisplayMode(). */
3831 ddraw1
= create_ddraw();
3832 ddraw2
= create_ddraw();
3833 hr
= set_display_mode(ddraw2
, 640, 480);
3834 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3835 w
= GetSystemMetrics(SM_CXSCREEN
);
3836 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3837 h
= GetSystemMetrics(SM_CYSCREEN
);
3838 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3840 ref
= IDirectDraw2_Release(ddraw1
);
3841 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3842 w
= GetSystemMetrics(SM_CXSCREEN
);
3843 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3844 h
= GetSystemMetrics(SM_CYSCREEN
);
3845 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3847 ref
= IDirectDraw2_Release(ddraw2
);
3848 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3849 w
= GetSystemMetrics(SM_CXSCREEN
);
3850 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3851 h
= GetSystemMetrics(SM_CYSCREEN
);
3852 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3854 /* If there's a ddraw object that's currently in exclusive mode, it blocks
3855 * restoring the display mode. */
3856 ddraw1
= create_ddraw();
3857 hr
= set_display_mode(ddraw1
, 800, 600);
3858 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3859 w
= GetSystemMetrics(SM_CXSCREEN
);
3860 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3861 h
= GetSystemMetrics(SM_CYSCREEN
);
3862 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3864 ddraw2
= create_ddraw();
3865 hr
= set_display_mode(ddraw2
, 640, 480);
3866 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3867 w
= GetSystemMetrics(SM_CXSCREEN
);
3868 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3869 h
= GetSystemMetrics(SM_CYSCREEN
);
3870 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3872 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3873 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3875 ref
= IDirectDraw2_Release(ddraw1
);
3876 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3877 w
= GetSystemMetrics(SM_CXSCREEN
);
3878 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3879 h
= GetSystemMetrics(SM_CYSCREEN
);
3880 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3882 ref
= IDirectDraw2_Release(ddraw2
);
3883 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3884 w
= GetSystemMetrics(SM_CXSCREEN
);
3885 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3886 h
= GetSystemMetrics(SM_CYSCREEN
);
3887 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3889 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
3890 ddraw1
= create_ddraw();
3891 hr
= set_display_mode(ddraw1
, 800, 600);
3892 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3893 w
= GetSystemMetrics(SM_CXSCREEN
);
3894 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3895 h
= GetSystemMetrics(SM_CYSCREEN
);
3896 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3898 hr
= IDirectDraw2_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3899 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3901 ddraw2
= create_ddraw();
3902 hr
= set_display_mode(ddraw2
, 640, 480);
3903 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
3905 ref
= IDirectDraw2_Release(ddraw1
);
3906 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3907 w
= GetSystemMetrics(SM_CXSCREEN
);
3908 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3909 h
= GetSystemMetrics(SM_CYSCREEN
);
3910 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3912 ref
= IDirectDraw2_Release(ddraw2
);
3913 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3914 w
= GetSystemMetrics(SM_CXSCREEN
);
3915 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3916 h
= GetSystemMetrics(SM_CYSCREEN
);
3917 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3919 if (display_count
< 2)
3921 skip("Following tests require two monitors.\n");
3925 ret
= restore_display_modes(original_modes
, display_count
);
3926 ok(ret
, "Failed to restore display modes.\n");
3928 second_monitor_name
[0] = '\0';
3929 for (display_idx
= 0; display_idx
< display_count
; ++display_idx
)
3931 if (original_modes
[display_idx
].dmPosition
.x
|| original_modes
[display_idx
].dmPosition
.y
)
3933 lstrcpyW(second_monitor_name
, original_modes
[display_idx
].dmDeviceName
);
3937 ok(lstrlenW(second_monitor_name
), "Got an empty second monitor name.\n");
3938 memset(&old_devmode
, 0, sizeof(old_devmode
));
3939 old_devmode
.dmSize
= sizeof(old_devmode
);
3940 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &old_devmode
);
3941 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3943 devmode
= old_devmode
;
3944 while (EnumDisplaySettingsW(second_monitor_name
, mode_idx
++, &devmode
))
3946 if (devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
3947 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
)
3950 ok(devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
3951 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
,
3952 "Failed to find a different mode for the second monitor.\n");
3954 /* Test that no mode restorations for non-primary monitors if SetDisplayMode() was not called */
3955 ddraw1
= create_ddraw();
3956 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3957 hr
= IDirectDraw2_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3958 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
3960 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
3961 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
3963 memset(&devmode2
, 0, sizeof(devmode2
));
3964 devmode2
.dmSize
= sizeof(devmode2
);
3965 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3966 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3967 if (compare_mode_rect(&devmode2
, &old_devmode
))
3969 skip("Failed to change display settings of the second monitor.\n");
3970 ref
= IDirectDraw2_Release(ddraw1
);
3971 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3975 hr
= IDirectDraw2_SetCooperativeLevel(ddraw1
, window
, DDSCL_NORMAL
);
3976 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
3977 ref
= IDirectDraw2_Release(ddraw1
);
3978 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3980 memset(&devmode3
, 0, sizeof(devmode3
));
3981 devmode3
.dmSize
= sizeof(devmode3
);
3982 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode3
);
3983 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3984 ok(compare_mode_rect(&devmode3
, &devmode2
), "Got a different mode.\n");
3985 ret
= restore_display_modes(original_modes
, display_count
);
3986 ok(ret
, "Failed to restore display modes.\n");
3988 /* Test that mode restorations happen for non-primary monitors on ddraw releases if
3989 * SetDisplayMode() was called */
3990 ddraw1
= create_ddraw();
3991 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3992 hr
= set_display_mode(ddraw1
, 800, 600);
3993 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
3995 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
3996 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
3998 ref
= IDirectDraw2_Release(ddraw1
);
3999 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4001 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4002 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4003 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4004 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4005 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4006 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4007 ret
= restore_display_modes(original_modes
, display_count
);
4008 ok(ret
, "Failed to restore display modes.\n");
4010 /* Test that mode restorations happen for non-primary monitors as well */
4011 ddraw1
= create_ddraw();
4012 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4013 hr
= set_display_mode(ddraw1
, 800, 600);
4014 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4016 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4017 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
4019 hr
= IDirectDraw2_RestoreDisplayMode(ddraw1
);
4020 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
4022 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4023 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4024 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4025 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4026 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4027 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4029 ref
= IDirectDraw2_Release(ddraw1
);
4030 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4031 ret
= restore_display_modes(original_modes
, display_count
);
4032 ok(ret
, "Failed to restore display modes.\n");
4034 /* Test that mode restorations for non-primary monitors use display settings in the registry */
4035 ddraw1
= create_ddraw();
4036 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4037 hr
= set_display_mode(ddraw1
, 800, 600);
4038 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4040 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
,
4041 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
4042 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
4044 ref
= IDirectDraw2_Release(ddraw1
);
4045 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4047 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4048 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4049 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4050 "Expected resolution %ux%u, got %ux%u.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4051 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4052 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4053 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4054 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4055 "Expected resolution %ux%u, got %ux%u.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4056 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4057 ret
= restore_display_modes(original_modes
, display_count
);
4058 ok(ret
, "Failed to restore display modes.\n");
4060 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4061 * objects and one of them restores display mode */
4062 ddraw1
= create_ddraw();
4063 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4064 ddraw2
= create_ddraw();
4065 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4066 hr
= set_display_mode(ddraw1
, 800, 600);
4067 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4068 hr
= set_display_mode(ddraw2
, 640, 480);
4069 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4071 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4072 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
4074 hr
= IDirectDraw2_RestoreDisplayMode(ddraw2
);
4075 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
4077 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4078 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4079 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4080 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4081 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4082 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4084 ref
= IDirectDraw2_Release(ddraw2
);
4085 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4086 ref
= IDirectDraw2_Release(ddraw1
);
4087 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4088 ret
= restore_display_modes(original_modes
, display_count
);
4089 ok(ret
, "Failed to restore display modes.\n");
4091 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4092 * objects and one of them got released */
4093 ddraw1
= create_ddraw();
4094 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4095 ddraw2
= create_ddraw();
4096 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4097 hr
= set_display_mode(ddraw1
, 800, 600);
4098 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4099 hr
= set_display_mode(ddraw2
, 640, 480);
4100 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4102 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4103 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
4105 ref
= IDirectDraw2_Release(ddraw2
);
4106 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4108 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4109 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4110 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4111 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4112 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4113 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4115 ref
= IDirectDraw2_Release(ddraw1
);
4116 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4119 DestroyWindow(window
);
4120 ret
= restore_display_modes(original_modes
, display_count
);
4121 ok(ret
, "Failed to restore display modes.\n");
4122 heap_free(original_modes
);
4125 static void test_initialize(void)
4127 IDirectDraw2
*ddraw
;
4130 ddraw
= create_ddraw();
4131 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4133 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
4134 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
4135 IDirectDraw2_Release(ddraw
);
4138 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw2
, (void **)&ddraw
);
4139 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw2 instance, hr %#x.\n", hr
);
4140 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
4141 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
4142 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
4143 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
4144 IDirectDraw2_Release(ddraw
);
4148 static void test_coop_level_surf_create(void)
4150 IDirectDrawSurface
*surface
;
4151 IDirectDraw2
*ddraw
;
4155 ddraw
= create_ddraw();
4156 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4158 memset(&ddsd
, 0, sizeof(ddsd
));
4159 ddsd
.dwSize
= sizeof(ddsd
);
4160 ddsd
.dwFlags
= DDSD_CAPS
;
4161 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4162 surface
= (void *)0xdeadbeef;
4163 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4164 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
4165 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4167 surface
= (void *)0xdeadbeef;
4168 hr
= IDirectDraw2_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4169 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
4170 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4172 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4173 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4175 surface
= (void *)0xdeadbeef;
4176 hr
= IDirectDraw2_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4177 ok(hr
== DDERR_INVALIDPARAMS
, "Unexpected hr %#x.\n", hr
);
4178 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4180 IDirectDraw2_Release(ddraw
);
4183 static void test_coop_level_multi_window(void)
4185 HWND window1
, window2
;
4186 IDirectDraw2
*ddraw
;
4189 window1
= create_window();
4190 window2
= create_window();
4191 ddraw
= create_ddraw();
4192 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4194 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
4195 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4196 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
4197 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4198 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
4199 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
4201 IDirectDraw2_Release(ddraw
);
4202 DestroyWindow(window2
);
4203 DestroyWindow(window1
);
4206 static void test_clear_rect_count(void)
4208 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4209 IDirect3DMaterial2
*white
, *red
, *green
, *blue
;
4210 IDirect3DViewport2
*viewport
;
4211 IDirect3DDevice2
*device
;
4212 IDirectDrawSurface
*rt
;
4213 IDirectDraw2
*ddraw
;
4218 window
= create_window();
4219 ddraw
= create_ddraw();
4220 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4221 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4223 skip("Failed to create a 3D device, skipping test.\n");
4224 IDirectDraw2_Release(ddraw
);
4225 DestroyWindow(window
);
4229 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
4230 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4232 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
4233 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
4234 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
4235 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
4237 viewport
= create_viewport(device
, 0, 0, 640, 480);
4238 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
4239 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
4241 viewport_set_background(device
, viewport
, white
);
4242 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
4243 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
4244 viewport_set_background(device
, viewport
, red
);
4245 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
4246 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
4247 viewport_set_background(device
, viewport
, green
);
4248 hr
= IDirect3DViewport2_Clear(viewport
, 0, NULL
, D3DCLEAR_TARGET
);
4249 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
4250 viewport_set_background(device
, viewport
, blue
);
4251 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
4252 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
4254 color
= get_surface_color(rt
, 320, 240);
4255 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x000000ff, 1)),
4256 "Got unexpected color 0x%08x.\n", color
);
4258 IDirectDrawSurface_Release(rt
);
4259 destroy_viewport(device
, viewport
);
4260 destroy_material(white
);
4261 destroy_material(red
);
4262 destroy_material(green
);
4263 destroy_material(blue
);
4264 IDirect3DDevice2_Release(device
);
4265 IDirectDraw2_Release(ddraw
);
4266 DestroyWindow(window
);
4269 static BOOL
test_mode_restored(IDirectDraw2
*ddraw
, HWND window
)
4271 DDSURFACEDESC ddsd1
, ddsd2
;
4274 memset(&ddsd1
, 0, sizeof(ddsd1
));
4275 ddsd1
.dwSize
= sizeof(ddsd1
);
4276 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd1
);
4277 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
4279 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4280 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4281 hr
= set_display_mode(ddraw
, 640, 480);
4282 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
4283 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4284 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4286 memset(&ddsd2
, 0, sizeof(ddsd2
));
4287 ddsd2
.dwSize
= sizeof(ddsd2
);
4288 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd2
);
4289 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
4290 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
4291 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
4293 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
4296 static void test_coop_level_versions(void)
4302 IDirectDrawSurface
*surface
;
4303 IDirectDraw2
*ddraw2
;
4306 window
= create_window();
4307 ddraw2
= create_ddraw();
4308 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4309 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
4310 restored
= test_mode_restored(ddraw2
, window
);
4311 ok(restored
, "Display mode not restored in new ddraw object\n");
4313 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
4314 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4315 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4317 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4318 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
4319 restored
= test_mode_restored(ddraw2
, window
);
4320 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
4322 /* A successful one does */
4323 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4324 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4325 restored
= test_mode_restored(ddraw2
, window
);
4326 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
4328 IDirectDraw_Release(ddraw
);
4329 IDirectDraw2_Release(ddraw2
);
4331 ddraw2
= create_ddraw();
4332 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4333 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4334 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4336 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
4337 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4338 restored
= test_mode_restored(ddraw2
, window
);
4339 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
4341 IDirectDraw_Release(ddraw
);
4342 IDirectDraw2_Release(ddraw2
);
4344 /* A failing call does not restore the ddraw2+ behavior */
4345 ddraw2
= create_ddraw();
4346 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4347 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4348 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4350 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4351 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4352 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4353 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
4354 restored
= test_mode_restored(ddraw2
, window
);
4355 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
4357 IDirectDraw_Release(ddraw
);
4358 IDirectDraw2_Release(ddraw2
);
4360 /* Neither does a sequence of successful calls with the new interface */
4361 ddraw2
= create_ddraw();
4362 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4363 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4364 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4366 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4367 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4368 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4369 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4370 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
4371 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4373 restored
= test_mode_restored(ddraw2
, window
);
4374 ok(!restored
, "Display mode restored after ddraw1-ddraw2 SetCooperativeLevel() call sequence\n");
4375 IDirectDraw_Release(ddraw
);
4376 IDirectDraw2_Release(ddraw2
);
4378 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
4379 ddraw2
= create_ddraw();
4380 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4381 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4382 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4384 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
4385 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4387 memset(&ddsd
, 0, sizeof(ddsd
));
4388 ddsd
.dwSize
= sizeof(ddsd
);
4389 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
4390 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
4391 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
4392 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4393 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#x.\n", hr
);
4394 IDirectDrawSurface_Release(surface
);
4395 restored
= test_mode_restored(ddraw2
, window
);
4396 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
4398 IDirectDraw_Release(ddraw
);
4399 IDirectDraw2_Release(ddraw2
);
4400 DestroyWindow(window
);
4403 static void test_lighting_interface_versions(void)
4405 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4406 IDirect3DMaterial2
*emissive
, *background
;
4407 IDirect3DViewport2
*viewport
;
4408 IDirect3DDevice2
*device
;
4409 IDirectDrawSurface
*rt
;
4410 IDirectDraw2
*ddraw
;
4414 D3DMATERIALHANDLE mat_handle
;
4418 static D3DVERTEX quad
[] =
4420 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4421 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4422 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4423 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4425 static D3DLVERTEX lquad
[] =
4427 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4428 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4429 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4430 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4432 static D3DTLVERTEX tlquad
[] =
4434 {{ 0.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4435 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4436 {{ 640.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4437 {{ 640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4441 D3DVERTEXTYPE vertextype
;
4443 DWORD d3drs_lighting
, d3drs_specular
;
4449 /* Lighting is enabled when D3DVT_VERTEX is used and D3DDP_DONOTLIGHT is not
4450 * set. D3DVT_VERTEX has diffuse = 0xffffffff and specular = 0x00000000, as
4451 * in later d3d versions */
4452 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, 0, 0x0000ff00},
4453 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, 0, 0x0000ff00},
4454 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4455 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4456 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, 0, 0x0000ff00},
4457 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, 0, 0x0000ff00},
4458 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4459 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4461 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, 0, 0x00ff0000},
4462 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, 0, 0x00ff0000},
4463 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4464 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4465 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, 0, 0x00ff8080},
4466 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, 0, 0x00ff8080},
4467 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4468 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4470 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, 0, 0x000000ff},
4471 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, 0, 0x000000ff},
4472 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
4473 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
4474 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, 0, 0x008080ff},
4475 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, 0, 0x008080ff},
4476 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
4477 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
4480 window
= create_window();
4481 ddraw
= create_ddraw();
4482 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4483 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4485 skip("Failed to create a 3D device, skipping test.\n");
4486 IDirectDraw2_Release(ddraw
);
4487 DestroyWindow(window
);
4491 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
4492 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4494 viewport
= create_viewport(device
, 0, 0, 640, 480);
4495 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
4496 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
4498 emissive
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
4499 hr
= IDirect3DMaterial2_GetHandle(emissive
, device
, &mat_handle
);
4500 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
4501 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
4502 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
4503 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
4504 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#x.\n", hr
);
4506 background
= create_diffuse_material(device
, 0.1f
, 0.1f
, 0.1f
, 0.1f
);
4507 viewport_set_background(device
, viewport
, background
);
4509 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, &rs
);
4510 ok(SUCCEEDED(hr
), "Failed to get specularenable render state, hr %#x.\n", hr
);
4511 ok(rs
== TRUE
, "Initial D3DRENDERSTATE_SPECULARENABLE is %#x, expected TRUE.\n", rs
);
4513 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
4515 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
4516 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
4518 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, tests
[i
].d3drs_lighting
);
4519 ok(SUCCEEDED(hr
), "Failed to set lighting render state, hr %#x.\n", hr
);
4520 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
,
4521 tests
[i
].d3drs_specular
);
4522 ok(SUCCEEDED(hr
), "Failed to set specularenable render state, hr %#x.\n", hr
);
4524 hr
= IDirect3DDevice2_BeginScene(device
);
4525 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4526 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
4527 tests
[i
].vertextype
, tests
[i
].data
, 4, tests
[i
].draw_flags
| D3DDP_WAIT
);
4528 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4529 hr
= IDirect3DDevice2_EndScene(device
);
4530 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4532 color
= get_surface_color(rt
, 320, 240);
4533 ok(compare_color(color
, tests
[i
].color
, 1),
4534 "Got unexpected color 0x%08x, expected 0x%08x, test %u.\n",
4535 color
, tests
[i
].color
, i
);
4538 destroy_material(background
);
4539 destroy_material(emissive
);
4540 destroy_viewport(device
, viewport
);
4541 IDirectDrawSurface_Release(rt
);
4542 IDirect3DDevice2_Release(device
);
4543 ref
= IDirectDraw2_Release(ddraw
);
4544 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
4545 DestroyWindow(window
);
4551 IDirectDraw2
*ddraw
;
4554 } activateapp_testdata
;
4556 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
4558 if (message
== WM_ACTIVATEAPP
)
4560 if (activateapp_testdata
.ddraw
)
4563 activateapp_testdata
.received
= FALSE
;
4564 hr
= IDirectDraw2_SetCooperativeLevel(activateapp_testdata
.ddraw
,
4565 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
4566 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#x.\n", hr
);
4567 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
4569 activateapp_testdata
.received
= TRUE
;
4572 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
4575 static void test_coop_level_activateapp(void)
4577 IDirectDraw2
*ddraw
;
4582 IDirectDrawSurface
*surface
;
4584 ddraw
= create_ddraw();
4585 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4587 wc
.lpfnWndProc
= activateapp_test_proc
;
4588 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
4589 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
4591 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
4592 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
4594 /* Exclusive with window already active. */
4595 SetForegroundWindow(window
);
4596 activateapp_testdata
.received
= FALSE
;
4597 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4598 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4599 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
4600 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4601 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4603 /* Exclusive with window not active. */
4604 SetForegroundWindow(GetDesktopWindow());
4605 activateapp_testdata
.received
= FALSE
;
4606 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4607 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4608 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4609 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4610 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4612 /* Normal with window not active, then exclusive with the same window. */
4613 SetForegroundWindow(GetDesktopWindow());
4614 activateapp_testdata
.received
= FALSE
;
4615 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4616 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4617 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
4618 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4619 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4620 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4621 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4622 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4624 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
4625 SetForegroundWindow(GetDesktopWindow());
4626 activateapp_testdata
.received
= FALSE
;
4627 activateapp_testdata
.ddraw
= ddraw
;
4628 activateapp_testdata
.window
= window
;
4629 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
4630 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4631 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4632 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4633 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4634 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4636 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
4637 * succeeding. Another switch to exclusive and back to normal is needed to release the
4638 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
4639 * WM_ACTIVATEAPP messages. */
4640 activateapp_testdata
.ddraw
= NULL
;
4641 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4642 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4643 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4644 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4646 /* Setting DDSCL_NORMAL with recursive invocation. */
4647 SetForegroundWindow(GetDesktopWindow());
4648 activateapp_testdata
.received
= FALSE
;
4649 activateapp_testdata
.ddraw
= ddraw
;
4650 activateapp_testdata
.window
= window
;
4651 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
4652 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4653 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4654 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4656 /* DDraw is in exclusive mode now. */
4657 memset(&ddsd
, 0, sizeof(ddsd
));
4658 ddsd
.dwSize
= sizeof(ddsd
);
4659 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
4660 ddsd
.dwBackBufferCount
= 1;
4661 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
4662 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4663 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4664 IDirectDrawSurface_Release(surface
);
4666 /* Recover again, just to be sure. */
4667 activateapp_testdata
.ddraw
= NULL
;
4668 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4669 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4670 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4671 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4673 DestroyWindow(window
);
4674 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
4675 IDirectDraw2_Release(ddraw
);
4678 struct format_support_check
4680 const DDPIXELFORMAT
*format
;
4684 static HRESULT WINAPI
test_unsupported_formats_cb(DDSURFACEDESC
*desc
, void *ctx
)
4686 struct format_support_check
*format
= ctx
;
4688 if (!memcmp(format
->format
, &desc
->ddpfPixelFormat
, sizeof(*format
->format
)))
4690 format
->supported
= TRUE
;
4691 return DDENUMRET_CANCEL
;
4694 return DDENUMRET_OK
;
4697 static void test_unsupported_formats(void)
4700 BOOL expect_success
;
4702 IDirectDraw2
*ddraw
;
4703 IDirect3DDevice2
*device
;
4704 IDirectDrawSurface
*surface
;
4707 DWORD expected_caps
;
4718 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
4719 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
4725 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
4726 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
4730 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
4732 window
= create_window();
4733 ddraw
= create_ddraw();
4734 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4735 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4737 skip("Failed to create a 3D device, skipping test.\n");
4738 IDirectDraw2_Release(ddraw
);
4739 DestroyWindow(window
);
4743 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
4745 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
4746 hr
= IDirect3DDevice2_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
4747 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
4749 for (j
= 0; j
< ARRAY_SIZE(caps
); j
++)
4751 memset(&ddsd
, 0, sizeof(ddsd
));
4752 ddsd
.dwSize
= sizeof(ddsd
);
4753 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
4754 ddsd
.ddpfPixelFormat
= formats
[i
].fmt
;
4757 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
4759 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
4760 expect_success
= FALSE
;
4762 expect_success
= TRUE
;
4764 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4765 ok(SUCCEEDED(hr
) == expect_success
,
4766 "Got unexpected hr %#x for format %s, caps %#x, expected %s.\n",
4767 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
4771 memset(&ddsd
, 0, sizeof(ddsd
));
4772 ddsd
.dwSize
= sizeof(ddsd
);
4773 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &ddsd
);
4774 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
4776 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
4777 expected_caps
= DDSCAPS_VIDEOMEMORY
;
4778 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
4779 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
4780 else if (check
.supported
)
4781 expected_caps
= DDSCAPS_VIDEOMEMORY
;
4783 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
4785 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
4786 "Expected capability %#x, format %s, input cap %#x.\n",
4787 expected_caps
, formats
[i
].name
, caps
[j
]);
4789 IDirectDrawSurface_Release(surface
);
4793 IDirect3DDevice2_Release(device
);
4794 IDirectDraw2_Release(ddraw
);
4795 DestroyWindow(window
);
4798 static void test_rt_caps(const GUID
*device_guid
)
4800 PALETTEENTRY palette_entries
[256];
4801 IDirectDrawPalette
*palette
;
4802 IDirect3DDevice2
*device
;
4803 BOOL software_device
;
4804 IDirectDraw2
*ddraw
;
4813 static const DDPIXELFORMAT p8_fmt
=
4815 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
4816 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
4821 const DDPIXELFORMAT
*pf
;
4823 HRESULT create_device_hr
;
4825 HRESULT alternative_set_rt_hr
;
4826 BOOL create_may_fail
;
4832 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
4840 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4848 DDSCAPS_OFFSCREENPLAIN
,
4856 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4857 D3DERR_SURFACENOTINVIDMEM
,
4864 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4872 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
4896 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4897 D3DERR_SURFACENOTINVIDMEM
,
4904 DDSCAPS_SYSTEMMEMORY
,
4920 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4921 DDERR_NOPALETTEATTACHED
,
4928 DDSCAPS_OFFSCREENPLAIN
,
4936 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4937 DDERR_NOPALETTEATTACHED
,
4944 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4952 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
4954 DDERR_INVALIDPIXELFORMAT
,
4956 TRUE
/* AMD Evergreen */,
4960 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
4962 DDERR_INVALIDPIXELFORMAT
,
4976 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
4978 DDERR_INVALIDPIXELFORMAT
,
4979 DDERR_INVALIDPIXELFORMAT
,
4980 TRUE
/* Nvidia Kepler */,
4984 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
4988 TRUE
/* Nvidia Kepler */,
4992 software_device
= is_software_device_type(device_guid
);
4994 window
= create_window();
4995 ddraw
= create_ddraw();
4996 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4997 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
4999 skip("Failed to create a 3D device, skipping test.\n");
5000 IDirectDraw2_Release(ddraw
);
5001 DestroyWindow(window
);
5004 z_depth
= get_device_z_depth(device
);
5005 ok(!!z_depth
, "Failed to get device z depth.\n");
5006 IDirect3DDevice2_Release(device
);
5008 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
5010 skip("D3D interface is not available, skipping test.\n");
5014 memset(palette_entries
, 0, sizeof(palette_entries
));
5015 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
5016 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
5018 memset(&hal_caps
, 0, sizeof(hal_caps
));
5019 hal_caps
.dwSize
= sizeof(hal_caps
);
5020 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
5021 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
5023 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5025 IDirectDrawSurface
*surface
, *rt
, *expected_rt
, *tmp
;
5026 DWORD caps_in
, expected_caps
;
5027 DDSURFACEDESC surface_desc
;
5028 IDirect3DDevice2
*device
;
5029 HRESULT expected_hr
;
5031 caps_in
= test_data
[i
].caps_in
;
5033 memset(&surface_desc
, 0, sizeof(surface_desc
));
5034 surface_desc
.dwSize
= sizeof(surface_desc
);
5035 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5036 surface_desc
.ddsCaps
.dwCaps
= caps_in
;
5037 if (test_data
[i
].pf
)
5039 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
5040 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
5042 if (caps_in
& DDSCAPS_ZBUFFER
)
5044 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
5045 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
5047 surface_desc
.dwWidth
= 640;
5048 surface_desc
.dwHeight
= 480;
5049 if ((caps_in
& DDSCAPS_VIDEOMEMORY
) && !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
5050 expected_hr
= DDERR_NODIRECTDRAWHW
;
5052 expected_hr
= DD_OK
;
5053 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5054 ok(hr
== expected_hr
|| broken(test_data
[i
].create_may_fail
5055 || (software_device
&& test_data
[i
].pf
== &p8_fmt
&& hr
== DDERR_INVALIDPIXELFORMAT
)),
5056 "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
5060 memset(&surface_desc
, 0, sizeof(surface_desc
));
5061 surface_desc
.dwSize
= sizeof(surface_desc
);
5062 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
5064 if ((caps_in
& DDSCAPS_SYSTEMMEMORY
) || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
5065 expected_caps
= caps_in
| DDSCAPS_SYSTEMMEMORY
;
5067 expected_caps
= caps_in
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
;
5069 ok(surface_desc
.ddsCaps
.dwCaps
== expected_caps
|| (test_data
[i
].pf
== &p8_fmt
5070 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
))
5071 || (software_device
&& caps_in
& DDSCAPS_ZBUFFER
5072 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
)),
5073 "Got unexpected caps %#x, expected %#x, test %u, software_device %u.\n",
5074 surface_desc
.ddsCaps
.dwCaps
, expected_caps
, i
, software_device
);
5076 hr
= IDirect3D2_CreateDevice(d3d
, device_guid
, surface
, &device
);
5078 ok((!software_device
&& hr
== test_data
[i
].create_device_hr
)
5079 || (software_device
&& (hr
== (test_data
[i
].create_device_hr
== D3DERR_SURFACENOTINVIDMEM
5080 ? DD_OK
: test_data
[i
].create_device_hr
))),
5081 "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
5085 if (hr
== DDERR_NOPALETTEATTACHED
)
5087 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
5088 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
5089 hr
= IDirect3D2_CreateDevice(d3d
, device_guid
, surface
, &device
);
5090 if (software_device
)
5092 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n",
5093 hr
, i
, software_device
);
5094 else if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
5095 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Got unexpected hr %#x, test %u, software_device %u.\n",
5096 hr
, i
, software_device
);
5098 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Got unexpected hr %#x, test %u, software_device %u.\n",
5099 hr
, i
, software_device
);
5103 refcount
= IDirect3DDevice2_Release(device
);
5104 ok(!refcount
, "Test %u: The device was not properly freed, refcount %u.\n", i
, refcount
);
5107 IDirectDrawSurface_Release(surface
);
5109 memset(&surface_desc
, 0, sizeof(surface_desc
));
5110 surface_desc
.dwSize
= sizeof(surface_desc
);
5111 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5112 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
5113 surface_desc
.dwWidth
= 640;
5114 surface_desc
.dwHeight
= 480;
5115 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5116 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
5118 hr
= IDirect3D2_CreateDevice(d3d
, device_guid
, surface
, &device
);
5119 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
5122 memset(&surface_desc
, 0, sizeof(surface_desc
));
5123 surface_desc
.dwSize
= sizeof(surface_desc
);
5124 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5125 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
5126 if (test_data
[i
].pf
)
5128 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
5129 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
5131 if (test_data
[i
].caps_in
& DDSCAPS_ZBUFFER
)
5133 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
5134 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
5136 surface_desc
.dwWidth
= 640;
5137 surface_desc
.dwHeight
= 480;
5138 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
5139 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
5141 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
5142 ok(hr
== test_data
[i
].set_rt_hr
|| (software_device
&& hr
== DDERR_NOPALETTEATTACHED
)
5143 || broken(hr
== test_data
[i
].alternative_set_rt_hr
),
5144 "Got unexpected hr %#x, test %u, software_device %u.\n",
5145 hr
, i
, software_device
);
5147 if (SUCCEEDED(hr
) || hr
== DDERR_INVALIDPIXELFORMAT
)
5150 expected_rt
= surface
;
5152 /* It appears the surface is set as render target in this case, but no
5153 * reference is taken. */
5154 if (hr
== DDERR_INVALIDPIXELFORMAT
)
5156 refcount
= IDirectDrawSurface_AddRef(rt
);
5157 ok(refcount
== 2, "Test %u: Got unexpected refcount %u.\n", i
, refcount
);
5160 hr
= IDirect3DDevice2_GetRenderTarget(device
, &tmp
);
5161 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
5162 ok(tmp
== expected_rt
, "Got unexpected rt %p, test %u, software_device %u.\n", tmp
, i
, software_device
);
5164 IDirectDrawSurface_Release(tmp
);
5165 IDirectDrawSurface_Release(rt
);
5166 refcount
= IDirect3DDevice2_Release(device
);
5167 ok(refcount
== 0, "Test %u: The device was not properly freed, refcount %u.\n", i
, refcount
);
5168 refcount
= IDirectDrawSurface_Release(surface
);
5169 ok(refcount
== 0, "Test %u: The surface was not properly freed, refcount %u.\n", i
, refcount
);
5172 IDirectDrawPalette_Release(palette
);
5173 IDirect3D2_Release(d3d
);
5176 refcount
= IDirectDraw2_Release(ddraw
);
5177 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
5178 DestroyWindow(window
);
5181 static void test_primary_caps(void)
5183 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
5184 IDirectDrawSurface
*surface
;
5185 DDSURFACEDESC surface_desc
;
5186 IDirectDraw2
*ddraw
;
5196 DWORD back_buffer_count
;
5204 DDSCAPS_PRIMARYSURFACE
,
5207 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
5211 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
5218 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
5225 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
5232 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
5239 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
5246 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5253 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5260 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5262 DDERR_NOEXCLUSIVEMODE
,
5266 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5267 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5273 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5274 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5277 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
5280 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5281 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
5287 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5288 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
5295 window
= create_window();
5296 ddraw
= create_ddraw();
5297 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5299 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5301 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
5302 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5304 memset(&surface_desc
, 0, sizeof(surface_desc
));
5305 surface_desc
.dwSize
= sizeof(surface_desc
);
5306 surface_desc
.dwFlags
= DDSD_CAPS
;
5307 if (test_data
[i
].back_buffer_count
!= ~0u)
5308 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
5309 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
5310 surface_desc
.dwBackBufferCount
= test_data
[i
].back_buffer_count
;
5311 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5312 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
5316 memset(&surface_desc
, 0, sizeof(surface_desc
));
5317 surface_desc
.dwSize
= sizeof(surface_desc
);
5318 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
5319 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
5320 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
5321 "Test %u: Got unexpected caps %#x, expected %#x.\n",
5322 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
5324 IDirectDrawSurface_Release(surface
);
5327 refcount
= IDirectDraw2_Release(ddraw
);
5328 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
5329 DestroyWindow(window
);
5332 static void test_surface_lock(void)
5334 IDirectDraw2
*ddraw
;
5335 IDirectDrawSurface
*surface
;
5336 IDirect3DDevice2
*device
;
5351 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
5352 "videomemory offscreenplain"
5355 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5356 "systemmemory offscreenplain"
5359 DDSCAPS_PRIMARYSURFACE
,
5363 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
5364 "videomemory texture"
5367 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
5368 "systemmemory texture"
5371 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5380 window
= create_window();
5381 ddraw
= create_ddraw();
5382 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5383 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
5385 skip("Failed to create a 3D device, skipping test.\n");
5386 IDirectDraw2_Release(ddraw
);
5387 DestroyWindow(window
);
5390 z_depth
= get_device_z_depth(device
);
5391 ok(!!z_depth
, "Failed to get device z depth.\n");
5392 IDirect3DDevice2_Release(device
);
5394 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5396 memset(&ddsd
, 0, sizeof(ddsd
));
5397 ddsd
.dwSize
= sizeof(ddsd
);
5398 ddsd
.dwFlags
= DDSD_CAPS
;
5399 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
5401 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
5405 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
5407 ddsd
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
5408 U2(ddsd
).dwZBufferBitDepth
= z_depth
;
5410 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
5412 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5413 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
5415 memset(&ddsd
, 0, sizeof(ddsd
));
5416 ddsd
.dwSize
= sizeof(ddsd
);
5417 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5418 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
5421 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5422 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
5425 memset(&ddsd
, 0, sizeof(ddsd
));
5426 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5427 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, tests
[i
].name
);
5429 IDirectDrawSurface_Release(surface
);
5432 refcount
= IDirectDraw2_Release(ddraw
);
5433 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
5434 DestroyWindow(window
);
5437 static void test_surface_discard(void)
5439 IDirectDraw2
*ddraw
;
5440 IDirect3DDevice2
*device
;
5444 IDirectDrawSurface
*surface
, *target
;
5453 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, TRUE
},
5454 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
5455 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, TRUE
},
5456 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
5460 window
= create_window();
5462 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5466 /* Sigh. Anything other than the first run of the loop randomly fails with
5467 * DDERR_SURFACELOST on my Radeon Pro 560 on Win10 19.09. Most of the time
5468 * the blit fails, but with sleeps added between surface creation and lock
5469 * the lock can fail too. Interestingly ddraw claims the render target has
5470 * been lost, not the test surface.
5472 * Recreating ddraw every iteration seems to fix this. */
5473 ddraw
= create_ddraw();
5474 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5475 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
5477 skip("Failed to create a 3D device, skipping test.\n");
5478 DestroyWindow(window
);
5479 IDirectDraw2_Release(ddraw
);
5483 hr
= IDirect3DDevice2_GetRenderTarget(device
, &target
);
5484 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
5486 memset(&ddsd
, 0, sizeof(ddsd
));
5487 ddsd
.dwSize
= sizeof(ddsd
);
5488 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5489 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
5492 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5495 skip("Failed to create surface, skipping.\n");
5499 memset(&ddsd
, 0, sizeof(ddsd
));
5500 ddsd
.dwSize
= sizeof(ddsd
);
5501 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5502 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
5503 addr
= ddsd
.lpSurface
;
5504 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5505 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5507 memset(&ddsd
, 0, sizeof(ddsd
));
5508 ddsd
.dwSize
= sizeof(ddsd
);
5509 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
5510 ok(SUCCEEDED(hr
) , "Failed to lock surface, hr %#x.\n", hr
);
5511 discarded
= ddsd
.lpSurface
!= addr
;
5512 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5513 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5515 hr
= IDirectDrawSurface_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
5516 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
5518 memset(&ddsd
, 0, sizeof(ddsd
));
5519 ddsd
.dwSize
= sizeof(ddsd
);
5520 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
5521 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
5522 discarded
|= ddsd
.lpSurface
!= addr
;
5523 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5524 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5526 IDirectDrawSurface_Release(surface
);
5528 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
5529 * AMD r500, evergreen). Windows XP, at least on AMD r200, never changes the pointer. */
5530 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
5532 IDirectDrawSurface_Release(target
);
5533 IDirect3DDevice2_Release(device
);
5534 IDirectDraw2_Release(ddraw
);
5537 DestroyWindow(window
);
5540 static void test_flip(void)
5542 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
5543 IDirectDrawSurface
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
5544 DDSCAPS caps
= {DDSCAPS_FLIP
};
5545 DDSURFACEDESC surface_desc
;
5546 BOOL sysmem_primary
;
5547 IDirectDraw2
*ddraw
;
5548 DWORD expected_caps
;
5562 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
5563 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
5564 {"TEXTURE", DDSCAPS_TEXTURE
},
5567 window
= create_window();
5568 ddraw
= create_ddraw();
5569 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5571 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5572 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5574 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5576 /* Creating a flippable texture induces a BSoD on some versions of the
5577 * Intel graphics driver. At least Intel GMA 950 with driver version
5578 * 6.14.10.4926 on Windows XP SP3 is affected. */
5579 if ((test_data
[i
].caps
& DDSCAPS_TEXTURE
) && ddraw_is_intel(ddraw
))
5581 win_skip("Skipping flippable texture test.\n");
5585 memset(&surface_desc
, 0, sizeof(surface_desc
));
5586 surface_desc
.dwSize
= sizeof(surface_desc
);
5587 surface_desc
.dwFlags
= DDSD_CAPS
;
5588 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
5589 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
5590 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
5591 surface_desc
.dwWidth
= 512;
5592 surface_desc
.dwHeight
= 512;
5593 surface_desc
.dwBackBufferCount
= 3;
5594 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5595 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5597 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
5598 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
5599 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5600 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5602 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
5603 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
5604 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5605 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5607 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
5608 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5609 todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
5610 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
5614 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
5615 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
5616 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
5617 ok(hr
== DD_OK
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5618 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5619 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
5620 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5622 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5623 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5624 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
5625 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
5626 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5627 hr
= restore_surfaces(ddraw
);
5628 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#x.\n", test_data
[i
].name
, hr
);
5630 memset(&surface_desc
, 0, sizeof(surface_desc
));
5631 surface_desc
.dwSize
= sizeof(surface_desc
);
5632 hr
= IDirectDrawSurface_GetSurfaceDesc(frontbuffer
, &surface_desc
);
5633 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
5634 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
5635 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
5636 expected_caps
|= DDSCAPS_VISIBLE
;
5637 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5638 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5639 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
5641 hr
= IDirectDrawSurface_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
5642 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
5643 memset(&surface_desc
, 0, sizeof(surface_desc
));
5644 surface_desc
.dwSize
= sizeof(surface_desc
);
5645 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer1
, &surface_desc
);
5646 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
5647 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
5648 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5649 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
5650 expected_caps
|= DDSCAPS_BACKBUFFER
;
5651 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5652 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5654 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
5655 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
5656 memset(&surface_desc
, 0, sizeof(surface_desc
));
5657 surface_desc
.dwSize
= sizeof(surface_desc
);
5658 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer2
, &surface_desc
);
5659 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
5660 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
5661 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5662 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
5663 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5664 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5666 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
5667 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
5668 memset(&surface_desc
, 0, sizeof(surface_desc
));
5669 surface_desc
.dwSize
= sizeof(surface_desc
);
5670 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer3
, &surface_desc
);
5671 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
5672 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
5673 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5674 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5675 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5677 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
5678 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
5679 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
5680 test_data
[i
].name
, surface
, frontbuffer
);
5681 IDirectDrawSurface_Release(surface
);
5683 memset(&surface_desc
, 0, sizeof(surface_desc
));
5684 surface_desc
.dwSize
= sizeof(surface_desc
);
5685 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5686 surface_desc
.ddsCaps
.dwCaps
= 0;
5687 surface_desc
.dwWidth
= 640;
5688 surface_desc
.dwHeight
= 480;
5689 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5690 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
5691 hr
= IDirectDrawSurface_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
5692 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5693 IDirectDrawSurface_Release(surface
);
5695 hr
= IDirectDrawSurface_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
5696 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5697 hr
= IDirectDrawSurface_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
5698 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5699 hr
= IDirectDrawSurface_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
5700 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5701 hr
= IDirectDrawSurface_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
5702 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
5704 /* The Nvidia Geforce 7 driver cannot do a color fill on a texture backbuffer after
5705 * the backbuffer has been locked or GetSurfaceDesc has been called. Do it ourselves
5706 * as a workaround. */
5707 fill_surface(backbuffer1
, 0xffff0000);
5708 fill_surface(backbuffer2
, 0xff00ff00);
5709 fill_surface(backbuffer3
, 0xff0000ff);
5711 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5712 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5713 color
= get_surface_color(backbuffer1
, 320, 240);
5714 /* The testbot seems to just copy the contents of one surface to all the
5715 * others, instead of properly flipping. */
5716 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
5717 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5718 color
= get_surface_color(backbuffer2
, 320, 240);
5719 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5720 fill_surface(backbuffer3
, 0xffff0000);
5722 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5723 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5724 color
= get_surface_color(backbuffer1
, 320, 240);
5725 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
5726 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5727 color
= get_surface_color(backbuffer2
, 320, 240);
5728 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5729 fill_surface(backbuffer3
, 0xff00ff00);
5731 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5732 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5733 color
= get_surface_color(backbuffer1
, 320, 240);
5734 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
5735 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5736 color
= get_surface_color(backbuffer2
, 320, 240);
5737 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5738 fill_surface(backbuffer3
, 0xff0000ff);
5740 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
5741 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5742 color
= get_surface_color(backbuffer2
, 320, 240);
5743 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
5744 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5745 color
= get_surface_color(backbuffer3
, 320, 240);
5746 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5747 fill_surface(backbuffer1
, 0xffff0000);
5749 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
5750 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5751 color
= get_surface_color(backbuffer1
, 320, 240);
5752 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5753 color
= get_surface_color(backbuffer3
, 320, 240);
5754 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
5755 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5756 fill_surface(backbuffer2
, 0xff00ff00);
5758 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
5759 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
5760 color
= get_surface_color(backbuffer1
, 320, 240);
5761 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
5762 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5763 color
= get_surface_color(backbuffer2
, 320, 240);
5764 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5766 IDirectDrawSurface_Release(backbuffer3
);
5767 IDirectDrawSurface_Release(backbuffer2
);
5768 IDirectDrawSurface_Release(backbuffer1
);
5769 IDirectDrawSurface_Release(frontbuffer
);
5772 refcount
= IDirectDraw2_Release(ddraw
);
5773 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
5774 DestroyWindow(window
);
5777 static void reset_ddsd(DDSURFACEDESC
*ddsd
)
5779 memset(ddsd
, 0, sizeof(*ddsd
));
5780 ddsd
->dwSize
= sizeof(*ddsd
);
5783 static void test_set_surface_desc(void)
5785 IDirectDraw2
*ddraw
;
5789 IDirectDrawSurface
*surface
;
5790 IDirectDrawSurface3
*surface3
;
5800 invalid_caps_tests
[] =
5802 {DDSCAPS_VIDEOMEMORY
, FALSE
, "videomemory plain"},
5803 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, TRUE
, "systemmemory texture"},
5804 {DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
, FALSE
, "systemmemory primary"},
5807 window
= create_window();
5808 ddraw
= create_ddraw();
5809 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5810 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5811 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5814 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
5817 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5818 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5819 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5820 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5821 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5822 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5823 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5825 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5826 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5828 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
5829 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
5830 IDirectDrawSurface_Release(surface
);
5833 ddsd
.dwFlags
= DDSD_LPSURFACE
;
5834 ddsd
.lpSurface
= data
;
5835 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5836 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5838 /* Redundantly setting the same lpSurface is not an error. */
5839 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5840 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5841 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5842 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5843 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
5844 ok(ddsd
.lpSurface
== NULL
, "lpSurface is %p, expected NULL.\n", ddsd
.lpSurface
);
5846 hr
= IDirectDrawSurface3_Lock(surface3
, NULL
, &ddsd
, 0, NULL
);
5847 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
5848 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
5849 ok(ddsd
.lpSurface
== data
, "lpSurface is %p, expected %p.\n", data
, data
);
5850 hr
= IDirectDrawSurface3_Unlock(surface3
, NULL
);
5851 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
5854 ddsd
.dwFlags
= DDSD_LPSURFACE
;
5855 ddsd
.lpSurface
= data
;
5856 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 1);
5857 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with flags=1 returned %#x.\n", hr
);
5859 ddsd
.lpSurface
= NULL
;
5860 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5861 ok(hr
== DDERR_INVALIDPARAMS
, "Setting lpSurface=NULL returned %#x.\n", hr
);
5863 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, NULL
, 0);
5864 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with NULL desc returned %#x.\n", hr
);
5866 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5867 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5868 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
5869 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
5871 /* Setting the caps is an error. This also means the original description cannot be reapplied. */
5872 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5873 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the original desc returned %#x.\n", hr
);
5875 ddsd
.dwFlags
= DDSD_CAPS
;
5876 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5877 ok(hr
== DDERR_INVALIDPARAMS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
5879 /* dwCaps = 0 is allowed, but ignored. */
5880 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_LPSURFACE
;
5881 ddsd
.lpSurface
= data
;
5882 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5883 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
5884 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5885 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5886 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
5887 ddsd
.ddsCaps
.dwCaps
= 0;
5888 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5889 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5891 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5892 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5893 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
5894 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
5896 /* Setting the height is allowed, but it cannot be set to 0, and only if LPSURFACE is set too. */
5898 ddsd
.dwFlags
= DDSD_HEIGHT
;
5900 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5901 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height without lpSurface returned %#x.\n", hr
);
5903 ddsd
.lpSurface
= data
;
5904 ddsd
.dwFlags
= DDSD_HEIGHT
| DDSD_LPSURFACE
;
5905 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5906 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5909 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5910 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height=0 returned %#x.\n", hr
);
5913 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5914 ok(SUCCEEDED(hr
), "GetSurfaceDesc failed, hr %#x.\n", hr
);
5915 ok(ddsd
.dwWidth
== 8, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
5916 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
5918 /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0. */
5920 ddsd
.dwFlags
= DDSD_PITCH
;
5921 U1(ddsd
).lPitch
= 8 * 4;
5922 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5923 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch without lpSurface or width returned %#x.\n", hr
);
5925 ddsd
.dwFlags
= DDSD_WIDTH
;
5927 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5928 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width without lpSurface or pitch returned %#x.\n", hr
);
5930 ddsd
.dwFlags
= DDSD_PITCH
| DDSD_LPSURFACE
;
5931 ddsd
.lpSurface
= data
;
5932 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5933 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch and lpSurface without width returned %#x.\n", hr
);
5935 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_LPSURFACE
;
5936 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5937 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width and lpSurface without pitch returned %#x.\n", hr
);
5939 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
5940 U1(ddsd
).lPitch
= 16 * 4;
5942 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5943 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5946 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
5947 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5948 ok(ddsd
.dwWidth
== 16, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
5949 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
5950 ok(U1(ddsd
).lPitch
== 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %u.\n", U1(ddsd
).lPitch
);
5952 /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise.
5954 * VMware rejects those calls, but all real drivers accept it. Mark the VMware behavior broken. */
5955 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
5956 U1(ddsd
).lPitch
= 4 * 4;
5957 ddsd
.lpSurface
= data
;
5958 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5959 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
5961 U1(ddsd
).lPitch
= 4;
5962 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5963 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
5965 U1(ddsd
).lPitch
= 16 * 4 + 1;
5966 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5967 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
5969 U1(ddsd
).lPitch
= 16 * 4 + 3;
5970 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5971 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
5973 U1(ddsd
).lPitch
= -4;
5974 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5975 ok(hr
== DDERR_INVALIDPARAMS
, "Setting negative pitch returned %#x.\n", hr
);
5977 U1(ddsd
).lPitch
= 16 * 4;
5978 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5979 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
5982 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
5983 U1(ddsd
).lPitch
= 0;
5985 ddsd
.lpSurface
= data
;
5986 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5987 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero pitch returned %#x.\n", hr
);
5989 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
5990 U1(ddsd
).lPitch
= 16 * 4;
5992 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
5993 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero width returned %#x.\n", hr
);
5995 /* Setting the pixelformat without LPSURFACE is an error, but with LPSURFACE it works. */
5996 ddsd
.dwFlags
= DDSD_PIXELFORMAT
;
5997 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5998 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5999 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6000 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6001 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6002 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6003 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6004 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the pixel format returned %#x.\n", hr
);
6006 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
6007 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6008 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6010 /* Can't set color keys. */
6012 ddsd
.dwFlags
= DDSD_CKSRCBLT
;
6013 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff0000;
6014 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff0000;
6015 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6016 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
6018 ddsd
.dwFlags
= DDSD_CKSRCBLT
| DDSD_LPSURFACE
;
6019 ddsd
.lpSurface
= data
;
6020 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6021 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
6023 IDirectDrawSurface3_Release(surface3
);
6025 /* Test mipmap texture. */
6027 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
6030 U2(ddsd
).dwMipMapCount
= 3;
6031 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
6032 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6033 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
|| hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
6037 skip("Mipmaps are not supported.\n");
6041 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
6042 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6043 IDirectDrawSurface_Release(surface
);
6045 /* Changing surface desc for mipmap fails even without changing any
6047 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6048 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
6051 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6052 ddsd
.lpSurface
= data
;
6053 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6054 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
6055 IDirectDrawSurface3_Release(surface3
);
6059 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
6062 U2(ddsd
).dwMipMapCount
= 3;
6063 ddsd
.lpSurface
= data
;
6064 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
6066 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6067 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
|| hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
6071 static DDSCAPS caps
= {DDSCAPS_TEXTURE
};
6072 IDirectDrawSurface3
*surface2
;
6074 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
6075 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6076 IDirectDrawSurface_Release(surface
);
6078 hr
= IDirectDrawSurface3_GetAttachedSurface(surface3
, &caps
, &surface2
);
6079 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6081 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface2
, &ddsd
);
6082 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6083 ok(ddsd
.dwWidth
== 4, "Got unexpected dwWidth %u.\n", ddsd
.dwWidth
);
6086 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
6089 U1(ddsd
).lPitch
= 16 * 4;
6090 ddsd
.lpSurface
= data
;
6091 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6092 todo_wine
ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6095 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
6098 U1(ddsd
).lPitch
= 8 * 4;
6099 ddsd
.lpSurface
= data
;
6100 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6101 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6104 /* _Lock causes access violation on Windows. */
6106 hr
= IDirectDrawSurface3_Lock(surface2
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
6107 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6108 IDirectDrawSurface3_Unlock(surface2
, NULL
);
6113 /* Causes access violation on Windows. */
6115 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
6118 U1(ddsd
).lPitch
= 4 * 4;
6119 ddsd
.lpSurface
= data
;
6120 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface2
, &ddsd
, 0);
6121 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6123 IDirectDrawSurface3_Release(surface2
);
6124 IDirectDrawSurface3_Release(surface3
);
6127 /* Test surface created with DDSD_LPSURFACE. */
6129 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_LPSURFACE
| DDSD_PITCH
;
6132 ddsd
.lpSurface
= data
;
6133 U1(ddsd
).lPitch
= 8 * 4;
6134 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6135 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6136 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
6138 /* SetSurfaceDesc needs systemmemory surfaces.
6140 * As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing DDSD_LINEARSIZE is moot. */
6141 for (i
= 0; i
< ARRAY_SIZE(invalid_caps_tests
); i
++)
6144 ddsd
.dwFlags
= DDSD_CAPS
;
6145 ddsd
.ddsCaps
.dwCaps
= invalid_caps_tests
[i
].caps
;
6146 if (!(invalid_caps_tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
6148 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6151 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6152 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6153 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6154 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6155 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6156 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6159 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6160 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
, "Got unexpected hr %#x.\n", hr
);
6163 skip("Cannot create a %s surface, skipping vidmem SetSurfaceDesc test.\n",
6164 invalid_caps_tests
[i
].name
);
6167 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
6168 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6169 IDirectDrawSurface_Release(surface
);
6172 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6173 ddsd
.lpSurface
= data
;
6174 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6175 if (invalid_caps_tests
[i
].supported
)
6177 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6181 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
6182 invalid_caps_tests
[i
].name
, hr
);
6184 /* Check priority of error conditions. */
6185 ddsd
.dwFlags
= DDSD_WIDTH
;
6186 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6187 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
6188 invalid_caps_tests
[i
].name
, hr
);
6191 IDirectDrawSurface3_Release(surface3
);
6195 ref
= IDirectDraw2_Release(ddraw
);
6196 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
6197 DestroyWindow(window
);
6200 static void test_user_memory_getdc(void)
6202 IDirectDraw2
*ddraw
;
6206 IDirectDrawSurface
*surface
;
6207 IDirectDrawSurface3
*surface3
;
6216 window
= create_window();
6217 ddraw
= create_ddraw();
6218 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6220 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6221 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6224 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
6227 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6228 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6229 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6230 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6231 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6232 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6233 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6234 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6235 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6237 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
6238 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#x.\n", hr
);
6239 IDirectDrawSurface_Release(surface
);
6241 memset(data
, 0xaa, sizeof(data
));
6243 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6244 ddsd
.lpSurface
= data
;
6245 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6246 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6248 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
6249 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6250 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
6251 ok(!!bitmap
, "Failed to get bitmap.\n");
6252 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
6253 ok(size
== sizeof(dib
), "Got unexpected size %d.\n", size
);
6254 ok(dib
.dsBm
.bmBits
== data
, "Got unexpected bits %p, expected %p.\n", dib
.dsBm
.bmBits
, data
);
6255 BitBlt(dc
, 0, 0, 16, 8, NULL
, 0, 0, WHITENESS
);
6256 BitBlt(dc
, 0, 8, 16, 8, NULL
, 0, 0, BLACKNESS
);
6257 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
6258 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6260 ok(data
[0][0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data
[0][0]);
6261 ok(data
[15][15] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data
[15][15]);
6263 ddsd
.dwFlags
= DDSD_LPSURFACE
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
;
6264 ddsd
.lpSurface
= data
;
6267 U1(ddsd
).lPitch
= sizeof(*data
);
6268 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6269 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6271 memset(data
, 0xaa, sizeof(data
));
6272 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
6273 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6274 BitBlt(dc
, 0, 0, 4, 8, NULL
, 0, 0, BLACKNESS
);
6275 BitBlt(dc
, 1, 1, 2, 2, NULL
, 0, 0, WHITENESS
);
6276 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
6277 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6279 for (y
= 0; y
< 4; y
++)
6281 for (x
= 0; x
< 4; x
++)
6283 if ((x
== 1 || x
== 2) && (y
== 1 || y
== 2))
6284 ok(data
[y
][x
] == 0xffffffff, "Expected color 0xffffffff on position %ux%u, got %#x.\n",
6287 ok(data
[y
][x
] == 0x00000000, "Expected color 0xaaaaaaaa on position %ux%u, got %#x.\n",
6291 ok(data
[0][5] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 5x0, got %#x.\n",
6293 ok(data
[7][3] == 0x00000000, "Expected color 0x00000000 on position 3x7, got %#x.\n",
6295 ok(data
[7][4] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 4x7, got %#x.\n",
6297 ok(data
[8][0] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 0x8, got %#x.\n",
6300 IDirectDrawSurface3_Release(surface3
);
6301 ref
= IDirectDraw2_Release(ddraw
);
6302 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
6303 DestroyWindow(window
);
6306 static void test_sysmem_overlay(void)
6308 IDirectDraw2
*ddraw
;
6312 IDirectDrawSurface
*surface
;
6315 window
= create_window();
6316 ddraw
= create_ddraw();
6317 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6319 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6320 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6323 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
6326 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
6327 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6328 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6329 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6330 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6331 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6332 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6333 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6334 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#x.\n", hr
);
6336 ref
= IDirectDraw2_Release(ddraw
);
6337 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
6338 DestroyWindow(window
);
6341 static void test_primary_palette(void)
6343 DDSCAPS surface_caps
= {DDSCAPS_FLIP
};
6344 IDirectDrawSurface
*primary
, *backbuffer
;
6345 PALETTEENTRY palette_entries
[256];
6346 IDirectDrawPalette
*palette
, *tmp
;
6347 DDSURFACEDESC surface_desc
;
6348 IDirectDraw2
*ddraw
;
6354 window
= create_window();
6355 ddraw
= create_ddraw();
6356 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6357 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
6359 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
6360 IDirectDraw2_Release(ddraw
);
6361 DestroyWindow(window
);
6364 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6365 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6367 memset(&surface_desc
, 0, sizeof(surface_desc
));
6368 surface_desc
.dwSize
= sizeof(surface_desc
);
6369 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
6370 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
6371 surface_desc
.dwBackBufferCount
= 1;
6372 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
6373 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6374 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
6375 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
6377 memset(palette_entries
, 0, sizeof(palette_entries
));
6378 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
6379 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6380 refcount
= get_refcount((IUnknown
*)palette
);
6381 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
6383 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6384 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
6385 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
6387 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
6388 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6390 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
6391 * and is generally somewhat broken with respect to 8 bpp / palette
6393 if (SUCCEEDED(IDirectDrawSurface_GetPalette(backbuffer
, &tmp
)))
6395 win_skip("Broken palette handling detected, skipping tests.\n");
6396 IDirectDrawPalette_Release(tmp
);
6397 IDirectDrawPalette_Release(palette
);
6398 /* The Windows 8 testbot keeps extra references to the primary and
6399 * backbuffer while in 8 bpp mode. */
6400 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
6401 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
6405 refcount
= get_refcount((IUnknown
*)palette
);
6406 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
6408 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6409 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
6410 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
6411 "Got unexpected palette caps %#x.\n", palette_caps
);
6413 hr
= IDirectDrawSurface_SetPalette(primary
, NULL
);
6414 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6415 refcount
= get_refcount((IUnknown
*)palette
);
6416 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
6418 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6419 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
6420 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
6422 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
6423 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6424 refcount
= get_refcount((IUnknown
*)palette
);
6425 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
6427 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
6428 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
6429 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
6430 IDirectDrawPalette_Release(tmp
);
6431 hr
= IDirectDrawSurface_GetPalette(backbuffer
, &tmp
);
6432 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
6434 refcount
= IDirectDrawPalette_Release(palette
);
6435 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
6436 refcount
= IDirectDrawPalette_Release(palette
);
6437 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6439 /* Note that this only seems to work when the palette is attached to the
6440 * primary surface. When attached to a regular surface, attempting to get
6441 * the palette here will cause an access violation. */
6442 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
6443 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
6445 hr
= IDirectDrawSurface_IsLost(primary
);
6446 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6448 memset(&surface_desc
, 0, sizeof(surface_desc
));
6449 surface_desc
.dwSize
= sizeof(surface_desc
);
6450 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
6451 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6452 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
6453 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
6454 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 8, "Got unexpected bit count %u.\n",
6455 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
6457 hr
= set_display_mode(ddraw
, 640, 480);
6458 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
6460 memset(&surface_desc
, 0, sizeof(surface_desc
));
6461 surface_desc
.dwSize
= sizeof(surface_desc
);
6462 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
6463 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6464 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
6465 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
6466 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 32
6467 || U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 24,
6468 "Got unexpected bit count %u.\n", U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
6470 hr
= IDirectDrawSurface_IsLost(primary
);
6471 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6472 hr
= IDirectDrawSurface_Restore(primary
);
6473 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
6474 hr
= IDirectDrawSurface_IsLost(primary
);
6475 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
6477 memset(&surface_desc
, 0, sizeof(surface_desc
));
6478 surface_desc
.dwSize
= sizeof(surface_desc
);
6479 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
6480 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6481 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
6482 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
6483 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 32
6484 || U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 24,
6485 "Got unexpected bit count %u.\n", U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
6488 refcount
= IDirectDrawSurface_Release(backbuffer
);
6489 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
6490 refcount
= IDirectDrawSurface_Release(primary
);
6491 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6492 refcount
= IDirectDraw2_Release(ddraw
);
6493 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6494 DestroyWindow(window
);
6497 static HRESULT WINAPI
surface_counter(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
6499 UINT
*surface_count
= context
;
6502 IDirectDrawSurface_Release(surface
);
6504 return DDENUMRET_OK
;
6507 static void test_surface_attachment(void)
6509 IDirectDrawSurface
*surface1
, *surface2
, *surface3
, *surface4
;
6510 DDSCAPS caps
= {DDSCAPS_TEXTURE
};
6511 DDSURFACEDESC surface_desc
;
6512 IDirectDraw2
*ddraw
;
6518 window
= create_window();
6519 ddraw
= create_ddraw();
6520 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6521 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6522 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6524 memset(&surface_desc
, 0, sizeof(surface_desc
));
6525 surface_desc
.dwSize
= sizeof(surface_desc
);
6526 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
6527 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
6528 U2(surface_desc
).dwMipMapCount
= 3;
6529 surface_desc
.dwWidth
= 128;
6530 surface_desc
.dwHeight
= 128;
6531 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6532 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6534 hr
= IDirectDrawSurface_GetAttachedSurface(surface1
, &caps
, &surface2
);
6535 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
6536 hr
= IDirectDrawSurface_GetAttachedSurface(surface2
, &caps
, &surface3
);
6537 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
6538 hr
= IDirectDrawSurface_GetAttachedSurface(surface3
, &caps
, &surface4
);
6539 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
6542 IDirectDrawSurface_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
6543 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
6545 IDirectDrawSurface_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
6546 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
6548 IDirectDrawSurface_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
6549 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
6551 memset(&surface_desc
, 0, sizeof(surface_desc
));
6552 surface_desc
.dwSize
= sizeof(surface_desc
);
6553 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6554 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6555 surface_desc
.dwWidth
= 16;
6556 surface_desc
.dwHeight
= 16;
6557 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
6558 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6560 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
6561 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6562 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
6563 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6564 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
6565 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6566 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
6567 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6568 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
6569 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6570 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
6571 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6573 IDirectDrawSurface_Release(surface4
);
6575 memset(&surface_desc
, 0, sizeof(surface_desc
));
6576 surface_desc
.dwSize
= sizeof(surface_desc
);
6577 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6578 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6579 surface_desc
.dwWidth
= 16;
6580 surface_desc
.dwHeight
= 16;
6581 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
6582 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6584 if (SUCCEEDED(hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
)))
6586 skip("Running on refrast, skipping some tests.\n");
6587 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface4
);
6588 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
6592 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6593 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
6594 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6595 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
6596 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6597 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
6598 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6599 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
6600 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6601 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
6602 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6605 IDirectDrawSurface_Release(surface4
);
6606 IDirectDrawSurface_Release(surface3
);
6607 IDirectDrawSurface_Release(surface2
);
6608 IDirectDrawSurface_Release(surface1
);
6610 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6611 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6613 /* Try a single primary and two offscreen plain surfaces. */
6614 memset(&surface_desc
, 0, sizeof(surface_desc
));
6615 surface_desc
.dwSize
= sizeof(surface_desc
);
6616 surface_desc
.dwFlags
= DDSD_CAPS
;
6617 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
6618 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6619 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6621 memset(&surface_desc
, 0, sizeof(surface_desc
));
6622 surface_desc
.dwSize
= sizeof(surface_desc
);
6623 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6624 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6625 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
6626 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
6627 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
6628 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6630 memset(&surface_desc
, 0, sizeof(surface_desc
));
6631 surface_desc
.dwSize
= sizeof(surface_desc
);
6632 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6633 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6634 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
6635 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
6636 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
6637 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6639 /* This one has a different size. */
6640 memset(&surface_desc
, 0, sizeof(surface_desc
));
6641 surface_desc
.dwSize
= sizeof(surface_desc
);
6642 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6643 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6644 surface_desc
.dwWidth
= 128;
6645 surface_desc
.dwHeight
= 128;
6646 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
6647 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6649 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6650 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
6651 /* Try the reverse without detaching first. */
6652 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
6653 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
6654 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
6655 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
6657 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
6658 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
6659 /* Try to detach reversed. */
6660 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
6661 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6662 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface1
);
6663 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
6665 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface3
);
6666 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
6667 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface3
);
6668 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
6670 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
6671 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6672 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
6673 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6675 IDirectDrawSurface_Release(surface4
);
6676 IDirectDrawSurface_Release(surface3
);
6677 IDirectDrawSurface_Release(surface2
);
6678 IDirectDrawSurface_Release(surface1
);
6680 /* Test depth surfaces of different sizes. */
6681 memset(&surface_desc
, 0, sizeof(surface_desc
));
6682 surface_desc
.dwSize
= sizeof(surface_desc
);
6683 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6684 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
6685 surface_desc
.dwWidth
= 64;
6686 surface_desc
.dwHeight
= 64;
6687 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6688 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
6690 memset(&surface_desc
, 0, sizeof(surface_desc
));
6691 surface_desc
.dwSize
= sizeof(surface_desc
);
6692 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
6693 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
6694 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6695 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
6696 U1(surface_desc
.ddpfPixelFormat
).dwZBufferBitDepth
= 16;
6697 U3(surface_desc
.ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
6698 surface_desc
.dwWidth
= 32;
6699 surface_desc
.dwHeight
= 32;
6700 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
6701 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
6702 surface_desc
.dwWidth
= 64;
6703 surface_desc
.dwHeight
= 64;
6704 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
6705 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
6706 surface_desc
.dwWidth
= 128;
6707 surface_desc
.dwHeight
= 128;
6708 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
6709 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
6711 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6712 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6714 IDirectDrawSurface2_DeleteAttachedSurface(surface1
, 0, surface2
);
6715 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface3
);
6716 ok(hr
== D3D_OK
, "Failed to attach depth buffer, hr %#x.\n", hr
);
6717 hr
= IDirectDrawSurface2_DeleteAttachedSurface(surface1
, 0, surface3
);
6718 ok(hr
== D3D_OK
, "Failed to detach depth buffer, hr %#x.\n", hr
);
6719 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
6720 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
6722 IDirectDrawSurface2_Release(surface4
);
6723 IDirectDrawSurface2_Release(surface3
);
6724 IDirectDrawSurface2_Release(surface2
);
6725 IDirectDrawSurface2_Release(surface1
);
6727 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
6728 memset(&surface_desc
, 0, sizeof(surface_desc
));
6729 surface_desc
.dwSize
= sizeof(surface_desc
);
6730 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6731 surface_desc
.dwWidth
= 64;
6732 surface_desc
.dwHeight
= 64;
6733 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
6734 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6735 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
6736 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
6737 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
6738 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
6739 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
6740 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6741 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6742 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
6743 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6745 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
6746 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
6747 U1(surface_desc
.ddpfPixelFormat
).dwZBufferBitDepth
= 16;
6748 U3(surface_desc
.ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
6749 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
6750 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6752 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6753 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
6754 refcount
= get_refcount((IUnknown
*)surface2
);
6755 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
6756 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6757 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
6759 /* Attaching while already attached to other surface. */
6760 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface2
);
6761 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
6762 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface3
, 0, surface2
);
6763 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
6764 IDirectDrawSurface_Release(surface3
);
6766 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
6767 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
6768 refcount
= get_refcount((IUnknown
*)surface2
);
6769 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
6771 /* Automatic detachment on release. */
6772 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6773 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
6774 refcount
= get_refcount((IUnknown
*)surface2
);
6775 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
6776 refcount
= IDirectDrawSurface_Release(surface1
);
6777 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6778 refcount
= IDirectDrawSurface_Release(surface2
);
6779 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6780 refcount
= IDirectDraw2_Release(ddraw
);
6781 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6782 DestroyWindow(window
);
6785 static void test_pixel_format(void)
6787 HWND window
, window2
= NULL
;
6788 HDC hdc
, hdc2
= NULL
;
6790 int format
, test_format
;
6791 PIXELFORMATDESCRIPTOR pfd
;
6792 IDirectDraw2
*ddraw
= NULL
;
6793 IDirectDrawClipper
*clipper
= NULL
;
6795 IDirectDrawSurface
*primary
= NULL
, *offscreen
;
6799 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
6800 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
6803 skip("Failed to create window\n");
6807 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
6808 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
6810 hdc
= GetDC(window
);
6813 skip("Failed to get DC\n");
6818 hdc2
= GetDC(window2
);
6820 gl
= LoadLibraryA("opengl32.dll");
6821 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
6823 format
= GetPixelFormat(hdc
);
6824 ok(format
== 0, "new window has pixel format %d\n", format
);
6826 ZeroMemory(&pfd
, sizeof(pfd
));
6827 pfd
.nSize
= sizeof(pfd
);
6829 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
6830 pfd
.iPixelType
= PFD_TYPE_RGBA
;
6831 pfd
.iLayerType
= PFD_MAIN_PLANE
;
6832 format
= ChoosePixelFormat(hdc
, &pfd
);
6835 skip("no pixel format available\n");
6839 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
6841 skip("failed to set pixel format\n");
6845 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
6847 skip("failed to set pixel format on second window\n");
6850 ReleaseDC(window2
, hdc2
);
6855 ddraw
= create_ddraw();
6856 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6858 test_format
= GetPixelFormat(hdc
);
6859 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6861 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6864 skip("Failed to set cooperative level, hr %#x.\n", hr
);
6868 test_format
= GetPixelFormat(hdc
);
6869 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6873 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
6874 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
6875 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
6876 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
6878 test_format
= GetPixelFormat(hdc
);
6879 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6881 test_format
= GetPixelFormat(hdc2
);
6882 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6885 memset(&ddsd
, 0, sizeof(ddsd
));
6886 ddsd
.dwSize
= sizeof(ddsd
);
6887 ddsd
.dwFlags
= DDSD_CAPS
;
6888 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
6890 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
6891 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
6893 test_format
= GetPixelFormat(hdc
);
6894 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6898 test_format
= GetPixelFormat(hdc2
);
6899 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6904 hr
= IDirectDrawSurface_SetClipper(primary
, clipper
);
6905 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
6907 test_format
= GetPixelFormat(hdc
);
6908 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6910 test_format
= GetPixelFormat(hdc2
);
6911 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6914 memset(&ddsd
, 0, sizeof(ddsd
));
6915 ddsd
.dwSize
= sizeof(ddsd
);
6916 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6917 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6918 ddsd
.dwWidth
= ddsd
.dwHeight
= 64;
6919 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &offscreen
, NULL
);
6920 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
6922 memset(&fx
, 0, sizeof(fx
));
6923 fx
.dwSize
= sizeof(fx
);
6924 hr
= IDirectDrawSurface_Blt(offscreen
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
6925 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
6927 test_format
= GetPixelFormat(hdc
);
6928 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6930 hr
= IDirectDrawSurface_Blt(primary
, NULL
, offscreen
, NULL
, DDBLT_WAIT
, NULL
);
6931 ok(SUCCEEDED(hr
), "Failed to blit to primary surface, hr %#x.\n", hr
);
6933 test_format
= GetPixelFormat(hdc
);
6934 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6938 test_format
= GetPixelFormat(hdc2
);
6939 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6942 IDirectDrawSurface_Release(offscreen
);
6945 if (primary
) IDirectDrawSurface_Release(primary
);
6946 if (clipper
) IDirectDrawClipper_Release(clipper
);
6947 if (ddraw
) IDirectDraw2_Release(ddraw
);
6948 if (gl
) FreeLibrary(gl
);
6949 if (hdc
) ReleaseDC(window
, hdc
);
6950 if (hdc2
) ReleaseDC(window2
, hdc2
);
6951 DestroyWindow(window
);
6952 if (window2
) DestroyWindow(window2
);
6955 static void test_create_surface_pitch(void)
6957 IDirectDrawSurface
*surface
;
6958 DDSURFACEDESC surface_desc
;
6959 IDirectDraw2
*ddraw
;
6979 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6981 DDSD_PITCH
, 0x100, 0x100},
6982 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6983 DDSD_PITCH
, 0x104, DD_OK
,
6984 DDSD_PITCH
, 0x100, 0x100},
6985 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6986 DDSD_PITCH
, 0x0f8, DD_OK
,
6987 DDSD_PITCH
, 0x100, 0x100},
6988 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6989 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
6991 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6993 DDSD_PITCH
, 0x100, 0x0fc},
6995 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6996 DDSD_PITCH
, 0x104, DD_OK
,
6997 DDSD_PITCH
, 0x100, 0x0fc},
6998 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6999 DDSD_PITCH
, 0x0f8, DD_OK
,
7000 DDSD_PITCH
, 0x100, 0x0fc},
7001 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7002 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
7003 DDSD_PITCH
, 0x100, 0x0fc},
7004 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7005 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
7007 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7008 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
7011 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
7012 0, 0, DDERR_INVALIDCAPS
,
7014 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7016 DDSD_PITCH
, 0x100, 0 },
7017 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7018 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
7020 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
7021 0, 0, DDERR_INVALIDCAPS
,
7023 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7025 DDSD_PITCH
, 0x100, 0 },
7027 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7028 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
7031 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
7033 window
= create_window();
7034 ddraw
= create_ddraw();
7035 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7036 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7037 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7039 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((63 * 4) + 8) * 63);
7041 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
7043 memset(&surface_desc
, 0, sizeof(surface_desc
));
7044 surface_desc
.dwSize
= sizeof(surface_desc
);
7045 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
7046 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
7047 surface_desc
.dwWidth
= 63;
7048 surface_desc
.dwHeight
= 63;
7049 U1(surface_desc
).lPitch
= test_data
[i
].pitch_in
;
7050 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7051 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7052 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
7053 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7054 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7055 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7056 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7057 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
7059 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
7060 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, expected_hr
);
7061 surface_desc
.lpSurface
= mem
;
7062 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7064 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
7066 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
7070 memset(&surface_desc
, 0, sizeof(surface_desc
));
7071 surface_desc
.dwSize
= sizeof(surface_desc
);
7072 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
7073 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
7074 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
7075 "Test %u: Got unexpected flags %#x, expected %#x.\n",
7076 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
7077 /* The pitch for textures seems to be implementation specific. */
7078 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
7080 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
7081 todo_wine
ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out64
,
7082 "Test %u: Got unexpected pitch %u, expected %u.\n",
7083 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out64
);
7085 ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out32
,
7086 "Test %u: Got unexpected pitch %u, expected %u.\n",
7087 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out32
);
7089 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
7091 IDirectDrawSurface_Release(surface
);
7094 HeapFree(GetProcessHeap(), 0, mem
);
7095 refcount
= IDirectDraw2_Release(ddraw
);
7096 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7097 DestroyWindow(window
);
7100 static void test_mipmap(void)
7102 IDirectDrawSurface
*surface1
;
7103 IDirectDrawSurface2
*surface
, *surface_base
, *surface_mip
;
7104 unsigned int i
, mipmap_count
;
7105 DDSURFACEDESC surface_desc
;
7106 IDirectDraw2
*ddraw
;
7110 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
7119 DWORD mipmap_count_in
;
7121 DWORD mipmap_count_out
;
7125 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
7126 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
, 0},
7127 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
7128 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
, 0},
7129 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 6},
7130 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 6},
7133 window
= create_window();
7134 ddraw
= create_ddraw();
7135 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7136 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7137 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7139 memset(&hal_caps
, 0, sizeof(hal_caps
));
7140 hal_caps
.dwSize
= sizeof(hal_caps
);
7141 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
7142 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
7143 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
7145 skip("Mipmapped textures not supported, skipping tests.\n");
7146 IDirectDraw2_Release(ddraw
);
7147 DestroyWindow(window
);
7151 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7153 memset(&surface_desc
, 0, sizeof(surface_desc
));
7154 surface_desc
.dwSize
= sizeof(surface_desc
);
7155 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
7156 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
7157 surface_desc
.dwWidth
= tests
[i
].width
;
7158 surface_desc
.dwHeight
= tests
[i
].height
;
7159 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
7160 U2(surface_desc
).dwMipMapCount
= tests
[i
].mipmap_count_in
;
7161 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7162 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
7166 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
7167 ok(SUCCEEDED(hr
), "Test %u: Failed to get IDirectDrawSurface2 interface, hr %#x.\n", i
, hr
);
7168 IDirectDrawSurface_Release(surface1
);
7170 memset(&surface_desc
, 0, sizeof(surface_desc
));
7171 surface_desc
.dwSize
= sizeof(surface_desc
);
7172 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface
, &surface_desc
);
7173 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
7174 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
7175 "Test %u: Got unexpected flags %#x.\n", i
, surface_desc
.dwFlags
);
7176 ok(U2(surface_desc
).dwMipMapCount
== tests
[i
].mipmap_count_out
,
7177 "Test %u: Got unexpected mipmap count %u.\n", i
, U2(surface_desc
).dwMipMapCount
);
7179 surface_base
= surface
;
7180 IDirectDrawSurface2_AddRef(surface_base
);
7181 mipmap_count
= U2(surface_desc
).dwMipMapCount
;
7182 while (mipmap_count
> 1)
7184 hr
= IDirectDrawSurface2_GetAttachedSurface(surface_base
, &caps
, &surface_mip
);
7185 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get attached surface, hr %#x.\n", i
, mipmap_count
, hr
);
7187 memset(&surface_desc
, 0, sizeof(surface_desc
));
7188 surface_desc
.dwSize
= sizeof(surface_desc
);
7189 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface_base
, &surface_desc
);
7190 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get surface desc, hr %#x.\n", i
, mipmap_count
, hr
);
7191 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
7192 "Test %u, %u: Got unexpected flags %#x.\n", i
, mipmap_count
, surface_desc
.dwFlags
);
7193 ok(U2(surface_desc
).dwMipMapCount
== mipmap_count
,
7194 "Test %u, %u: Got unexpected mipmap count %u.\n",
7195 i
, mipmap_count
, U2(surface_desc
).dwMipMapCount
);
7197 memset(&surface_desc
, 0, sizeof(surface_desc
));
7198 surface_desc
.dwSize
= sizeof(surface_desc
);
7199 hr
= IDirectDrawSurface2_Lock(surface_base
, NULL
, &surface_desc
, 0, NULL
);
7200 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#x.\n", i
, mipmap_count
, hr
);
7201 ok(surface_desc
.dwMipMapCount
== mipmap_count
,
7202 "Test %u, %u: unexpected change of mipmap count %u.\n",
7203 i
, mipmap_count
, surface_desc
.dwMipMapCount
);
7204 memset(&surface_desc
, 0, sizeof(surface_desc
));
7205 surface_desc
.dwSize
= sizeof(surface_desc
);
7206 hr
= IDirectDrawSurface2_Lock(surface_mip
, NULL
, &surface_desc
, 0, NULL
);
7207 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#x.\n", i
, mipmap_count
, hr
);
7208 ok(surface_desc
.dwMipMapCount
== mipmap_count
- 1,
7209 "Test %u, %u: Child mipmap count unexpected %u\n", i
, mipmap_count
, surface_desc
.dwMipMapCount
);
7210 IDirectDrawSurface2_Unlock(surface_mip
, NULL
);
7211 IDirectDrawSurface2_Unlock(surface_base
, NULL
);
7213 IDirectDrawSurface2_Release(surface_base
);
7214 surface_base
= surface_mip
;
7217 IDirectDrawSurface2_Release(surface_base
);
7219 IDirectDrawSurface2_Release(surface
);
7222 refcount
= IDirectDraw2_Release(ddraw
);
7223 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7224 DestroyWindow(window
);
7227 static void test_palette_complex(void)
7229 IDirectDrawSurface
*surface1
;
7230 IDirectDrawSurface2
*surface
, *mipmap
, *tmp
;
7231 DDSURFACEDESC surface_desc
;
7232 IDirectDraw2
*ddraw
;
7233 IDirectDrawPalette
*palette
, *palette2
, *palette_mipmap
;
7237 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
7239 PALETTEENTRY palette_entries
[256];
7245 window
= create_window();
7246 ddraw
= create_ddraw();
7247 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7248 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7249 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7251 memset(&hal_caps
, 0, sizeof(hal_caps
));
7252 hal_caps
.dwSize
= sizeof(hal_caps
);
7253 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
7254 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
7255 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
7257 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
7258 IDirectDraw2_Release(ddraw
);
7259 DestroyWindow(window
);
7263 memset(&surface_desc
, 0, sizeof(surface_desc
));
7264 surface_desc
.dwSize
= sizeof(surface_desc
);
7265 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7266 surface_desc
.dwWidth
= 128;
7267 surface_desc
.dwHeight
= 128;
7268 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7269 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7270 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
7271 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
7272 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7273 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7274 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
7275 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr
);
7276 IDirectDrawSurface_Release(surface1
);
7278 memset(palette_entries
, 0, sizeof(palette_entries
));
7279 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7280 palette_entries
, &palette
, NULL
);
7281 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7283 memset(palette_entries
, 0, sizeof(palette_entries
));
7284 palette_entries
[1].peRed
= 0xff;
7285 palette_entries
[1].peGreen
= 0x80;
7286 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7287 palette_entries
, &palette_mipmap
, NULL
);
7288 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7290 palette2
= (void *)0xdeadbeef;
7291 hr
= IDirectDrawSurface2_GetPalette(surface
, &palette2
);
7292 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
7293 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
7294 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
7295 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7296 hr
= IDirectDrawSurface2_GetPalette(surface
, &palette2
);
7297 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
7298 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
7299 IDirectDrawPalette_Release(palette2
);
7302 IDirectDrawSurface2_AddRef(mipmap
);
7303 for (i
= 0; i
< 7; ++i
)
7305 hr
= IDirectDrawSurface2_GetAttachedSurface(mipmap
, &caps
, &tmp
);
7306 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
7307 palette2
= (void *)0xdeadbeef;
7308 hr
= IDirectDrawSurface2_GetPalette(tmp
, &palette2
);
7309 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
7310 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
7312 hr
= IDirectDrawSurface2_SetPalette(tmp
, palette_mipmap
);
7313 ok(SUCCEEDED(hr
), "Failed to set palette, i %u, hr %#x.\n", i
, hr
);
7315 hr
= IDirectDrawSurface2_GetPalette(tmp
, &palette2
);
7316 ok(SUCCEEDED(hr
), "Failed to get palette, i %u, hr %#x.\n", i
, hr
);
7317 ok(palette_mipmap
== palette2
, "Got unexpected palette %p.\n", palette2
);
7318 IDirectDrawPalette_Release(palette2
);
7320 hr
= IDirectDrawSurface2_GetDC(tmp
, &dc
);
7321 ok(SUCCEEDED(hr
), "Failed to get DC, i %u, hr %#x.\n", i
, hr
);
7322 count
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
7323 ok(count
== 1, "Expected count 1, got %u.\n", count
);
7324 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x.\n", rgbquad
.rgbRed
);
7325 ok(rgbquad
.rgbGreen
== 0x80, "Expected rgbGreen = 0x80, got %#x.\n", rgbquad
.rgbGreen
);
7326 ok(rgbquad
.rgbBlue
== 0x0, "Expected rgbBlue = 0x0, got %#x.\n", rgbquad
.rgbBlue
);
7327 hr
= IDirectDrawSurface2_ReleaseDC(tmp
, dc
);
7328 ok(SUCCEEDED(hr
), "Failed to release DC, i %u, hr %#x.\n", i
, hr
);
7330 IDirectDrawSurface2_Release(mipmap
);
7334 hr
= IDirectDrawSurface2_GetAttachedSurface(mipmap
, &caps
, &tmp
);
7335 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7336 IDirectDrawSurface2_Release(mipmap
);
7337 refcount
= IDirectDrawSurface2_Release(surface
);
7338 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7339 refcount
= IDirectDrawPalette_Release(palette_mipmap
);
7340 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7341 refcount
= IDirectDrawPalette_Release(palette
);
7342 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7344 refcount
= IDirectDraw2_Release(ddraw
);
7345 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7346 DestroyWindow(window
);
7349 static void test_p8_blit(void)
7351 IDirectDrawSurface
*src
, *dst
, *dst_p8
;
7352 DDSURFACEDESC surface_desc
;
7353 IDirectDraw2
*ddraw
;
7354 IDirectDrawPalette
*palette
, *palette2
;
7358 PALETTEENTRY palette_entries
[256];
7362 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
7363 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
7364 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
7365 static const D3DCOLOR expected
[] =
7367 0x00101010, 0x00010101, 0x00020202, 0x00030303,
7368 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
7372 window
= create_window();
7373 ddraw
= create_ddraw();
7374 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7375 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7376 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7377 is_warp
= ddraw_is_warp(ddraw
);
7379 memset(palette_entries
, 0, sizeof(palette_entries
));
7380 palette_entries
[1].peGreen
= 0xff;
7381 palette_entries
[2].peBlue
= 0xff;
7382 palette_entries
[3].peFlags
= 0xff;
7383 palette_entries
[4].peRed
= 0xff;
7384 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7385 palette_entries
, &palette
, NULL
);
7386 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7387 palette_entries
[1].peBlue
= 0xff;
7388 palette_entries
[2].peGreen
= 0xff;
7389 palette_entries
[3].peRed
= 0xff;
7390 palette_entries
[4].peFlags
= 0x0;
7391 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7392 palette_entries
, &palette2
, NULL
);
7393 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7395 memset(&surface_desc
, 0, sizeof(surface_desc
));
7396 surface_desc
.dwSize
= sizeof(surface_desc
);
7397 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7398 surface_desc
.dwWidth
= 8;
7399 surface_desc
.dwHeight
= 1;
7400 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7401 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7402 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
7403 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
7404 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
7405 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7406 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
7407 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7408 hr
= IDirectDrawSurface_SetPalette(dst_p8
, palette2
);
7409 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7411 memset(&surface_desc
, 0, sizeof(surface_desc
));
7412 surface_desc
.dwSize
= sizeof(surface_desc
);
7413 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7414 surface_desc
.dwWidth
= 8;
7415 surface_desc
.dwHeight
= 1;
7416 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7417 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7418 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
7419 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
7420 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7421 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7422 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7423 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
7424 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
7425 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7427 memset(&surface_desc
, 0, sizeof(surface_desc
));
7428 surface_desc
.dwSize
= sizeof(surface_desc
);
7429 hr
= IDirectDrawSurface_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
7430 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
7431 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
7432 hr
= IDirectDrawSurface_Unlock(src
, NULL
);
7433 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
7435 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
7436 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
7437 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
7438 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
7439 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
7441 fx
.dwSize
= sizeof(fx
);
7442 fx
.dwFillColor
= 0xdeadbeef;
7443 hr
= IDirectDrawSurface_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
7444 ok(SUCCEEDED(hr
), "Failed to color fill %#x.\n", hr
);
7446 hr
= IDirectDrawSurface_SetPalette(src
, palette
);
7447 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7448 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
7449 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
7450 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
7451 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
7452 "Failed to blit, hr %#x.\n", hr
);
7456 for (x
= 0; x
< ARRAY_SIZE(expected
); x
++)
7458 color
= get_surface_color(dst
, x
, 0);
7459 /* WARP on 1709 and newer write zeroes on non-colorkeyed P8 -> RGB blits. For ckey
7460 * blits see below. */
7461 todo_wine
ok(compare_color(color
, expected
[x
], 0)
7462 || broken(is_warp
&& compare_color(color
, 0x00000000, 0)),
7463 "Pixel %u: Got color %#x, expected %#x.\n",
7464 x
, color
, expected
[x
]);
7468 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
7469 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
7470 hr
= IDirectDrawSurface7_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
7471 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
7473 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
7474 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
7475 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
7476 * surface untouched. Error checking (DDBLT_KEYSRC without a key
7477 * for example) also works as expected.
7479 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
7480 * the display mode set to P8 doesn't help either. */
7481 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
7482 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
7483 "Got unexpected P8 color key blit result.\n");
7484 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
7485 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
7487 IDirectDrawSurface_Release(src
);
7488 IDirectDrawSurface_Release(dst
);
7489 IDirectDrawSurface_Release(dst_p8
);
7490 IDirectDrawPalette_Release(palette
);
7491 IDirectDrawPalette_Release(palette2
);
7493 refcount
= IDirectDraw2_Release(ddraw
);
7494 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7495 DestroyWindow(window
);
7498 static void test_material(void)
7500 IDirect3DMaterial2
*background
, *material
;
7501 D3DMATERIALHANDLE mat_handle
, tmp
;
7502 IDirect3DViewport2
*viewport
;
7503 IDirect3DDevice2
*device
;
7504 IDirectDrawSurface
*rt
;
7505 IDirectDraw2
*ddraw
;
7513 static D3DVERTEX quad
[] =
7515 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7516 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7517 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7518 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7523 D3DCOLOR expected_color
;
7528 {FALSE
, 0x00ffffff},
7530 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
7532 window
= create_window();
7533 ddraw
= create_ddraw();
7534 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7535 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7537 skip("Failed to create a 3D device, skipping test.\n");
7538 DestroyWindow(window
);
7542 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
7543 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
7545 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
7546 viewport
= create_viewport(device
, 0, 0, 640, 480);
7547 viewport_set_background(device
, viewport
, background
);
7548 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
7549 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
7551 material
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
7552 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
7553 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
7555 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
7556 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
7557 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
7558 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
7559 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
7560 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
7561 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
7562 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
7563 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, 0);
7564 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
7565 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
7566 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
7567 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
7569 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
7571 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
7572 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
7574 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, test_data
[i
].material
? mat_handle
: 0);
7575 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
7577 hr
= IDirect3DDevice2_BeginScene(device
);
7578 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7579 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_VERTEX
, quad
, 4, 0);
7580 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7581 hr
= IDirect3DDevice2_EndScene(device
);
7582 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7583 color
= get_surface_color(rt
, 320, 240);
7584 ok(compare_color(color
, test_data
[i
].expected_color
, 1),
7585 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
7588 destroy_material(material
);
7589 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
7590 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
7591 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
7593 hr
= IDirect3DViewport2_SetBackground(viewport
, mat_handle
);
7594 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
7595 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
7596 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
7597 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
7598 ok(valid
, "Got unexpected valid %#x.\n", valid
);
7599 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7600 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
7601 color
= get_surface_color(rt
, 320, 240);
7602 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
7604 hr
= IDirect3DViewport2_SetBackground(viewport
, 0);
7605 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7606 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
7607 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
7608 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
7609 ok(valid
, "Got unexpected valid %#x.\n", valid
);
7610 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7611 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
7612 color
= get_surface_color(rt
, 320, 240);
7613 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
7615 destroy_viewport(device
, viewport
);
7616 viewport
= create_viewport(device
, 0, 0, 640, 480);
7618 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
7619 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
7620 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
7621 ok(!valid
, "Got unexpected valid %#x.\n", valid
);
7622 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7623 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
7624 color
= get_surface_color(rt
, 320, 240);
7625 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color
);
7627 destroy_viewport(device
, viewport
);
7628 destroy_material(background
);
7629 destroy_material(material
);
7630 IDirectDrawSurface_Release(rt
);
7631 refcount
= IDirect3DDevice2_Release(device
);
7632 ok(!refcount
, "Device has %u references left.\n", refcount
);
7633 refcount
= IDirectDraw2_Release(ddraw
);
7634 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
7635 DestroyWindow(window
);
7638 static void test_lighting(void)
7640 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
7641 static D3DMATRIX mat
=
7643 1.0f
, 0.0f
, 0.0f
, 0.0f
,
7644 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7645 0.0f
, 0.0f
, 1.0f
, 0.0f
,
7646 0.0f
, 0.0f
, 0.0f
, 1.0f
,
7650 1.0f
, 0.0f
, 1.0f
, 0.0f
,
7651 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7652 1.0f
, 0.0f
, 1.0f
, 0.0f
,
7653 0.0f
, 0.0f
, 0.5f
, 1.0f
,
7657 0.0f
, 0.0f
, 1.0f
, 0.0f
,
7658 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7659 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
7660 10.f
, 10.0f
, 10.0f
, 1.0f
,
7664 1.0f
, 0.0f
, 0.0f
, 0.0f
,
7665 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7666 0.0f
, 0.0f
, 1.0f
, -1.0f
,
7667 10.f
, 10.0f
, 10.0f
, 0.0f
,
7669 static D3DLVERTEX unlitquad
[] =
7671 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
7672 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
7673 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
7674 {{ 0.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
7678 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
7679 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
7680 {{ 0.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
7681 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
7683 static D3DVERTEX unlitnquad
[] =
7685 {{0.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7686 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7687 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7688 {{1.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7692 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7693 {{0.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7694 {{1.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7695 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7699 {{-1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7700 {{-1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7701 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7702 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7706 {{-10.0f
}, {-11.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
7707 {{-10.0f
}, { -9.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
7708 {{-10.0f
}, { -9.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
7709 {{-10.0f
}, {-11.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
7713 {{-11.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7714 {{-11.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7715 {{ -9.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7716 {{ -9.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7718 static WORD indices
[] = {0, 1, 2, 2, 3, 0};
7721 D3DMATRIX
*world_matrix
;
7724 const char *message
;
7728 {&mat
, nquad
, 0x000060ff, "Lit quad with light"},
7729 {&mat_singular
, nquad
, 0x00004db4, "Lit quad with singular world matrix"},
7730 {&mat_transf
, rotatedquad
, 0x000060ff, "Lit quad with transformation matrix"},
7731 {&mat_nonaffine
, translatedquad
, 0x000060ff, "Lit quad with non-affine matrix"},
7734 IDirect3DViewport2
*viewport
, *viewport2
;
7735 D3DMATERIALHANDLE mat_handle
;
7736 IDirect3DMaterial2
*material
;
7737 IDirect3DDevice2
*device
;
7738 IDirectDrawSurface
*rt
;
7739 IDirect3DLight
*light
;
7740 D3DLIGHT2 light_desc
;
7741 IDirectDraw2
*ddraw
;
7749 window
= create_window();
7750 ddraw
= create_ddraw();
7751 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7752 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7754 skip("Failed to create a 3D device, skipping test.\n");
7755 DestroyWindow(window
);
7759 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
7760 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7762 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
7763 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7765 viewport
= create_viewport(device
, 0, 0, 640, 480);
7766 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
7767 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7769 material
= create_diffuse_and_ambient_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
7770 viewport_set_background(device
, viewport
, material
);
7772 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7773 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
7775 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
7776 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
7777 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
7778 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
7779 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
7780 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
7781 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
7782 ok(SUCCEEDED(hr
), "Failed to disable zbuffer, hr %#x.\n", hr
);
7783 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
7784 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
7785 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
7786 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
7788 hr
= IDirect3DDevice2_BeginScene(device
);
7789 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7791 /* There is no D3DRENDERSTATE_LIGHTING on ddraw < 7. */
7792 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
7793 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
7794 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_LVERTEX
, unlitquad
,
7796 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7798 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
7799 ok(SUCCEEDED(hr
), "Failed to enable lighting, hr %#x.\n", hr
);
7800 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_LVERTEX
, litquad
,
7802 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7804 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
7805 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
7806 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, unlitnquad
,
7808 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7810 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
7811 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
7812 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, litnquad
,
7814 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7816 hr
= IDirect3DDevice2_EndScene(device
);
7817 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7819 color
= get_surface_color(rt
, 160, 360);
7820 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color
);
7821 color
= get_surface_color(rt
, 160, 120);
7822 ok(color
== 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color
);
7823 color
= get_surface_color(rt
, 480, 360);
7824 ok(color
== 0x00ffffff, "Unlit quad with normals has color 0x%08x.\n", color
);
7825 color
= get_surface_color(rt
, 480, 120);
7826 ok(color
== 0x00ffffff, "Lit quad with normals has color 0x%08x.\n", color
);
7828 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
7829 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7830 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
7831 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7832 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_AMBIENT
, 0xff002000);
7833 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7835 hr
= IDirect3D2_CreateLight(d3d
, &light
, NULL
);
7836 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7837 memset(&light_desc
, 0, sizeof(light_desc
));
7838 light_desc
.dwSize
= sizeof(light_desc
);
7839 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
7840 U1(light_desc
.dcvColor
).r
= 0.0f
;
7841 U2(light_desc
.dcvColor
).g
= 0.25f
;
7842 U3(light_desc
.dcvColor
).b
= 1.0f
;
7843 U4(light_desc
.dcvColor
).a
= 1.0f
;
7844 U3(light_desc
.dvDirection
).z
= 1.0f
;
7845 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
7846 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7847 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
7848 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7849 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
7850 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
7852 viewport2
= create_viewport(device
, 0, 0, 640, 480);
7853 hr
= IDirect3DViewport2_AddLight(viewport2
, light
);
7854 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
7855 destroy_viewport(device
, viewport2
);
7857 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7858 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7860 hr
= IDirect3DDevice2_BeginScene(device
);
7861 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7863 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, nquad
,
7865 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7867 hr
= IDirect3DDevice2_EndScene(device
);
7868 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7870 color
= get_surface_color(rt
, 320, 240);
7871 ok(color
== 0x00002000, "Lit quad with no light has color 0x%08x.\n", color
);
7873 light_desc
.dwFlags
= D3DLIGHT_ACTIVE
;
7874 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
7875 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7876 hr
= IDirect3DViewport2_DeleteLight(viewport
, light
);
7877 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7878 light_desc
.dwFlags
= 0;
7879 hr
= IDirect3DLight_GetLight(light
, (D3DLIGHT
*)&light_desc
);
7880 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7881 ok(light_desc
.dwFlags
== D3DLIGHT_ACTIVE
, "Got unexpected flags %#x.\n", light_desc
.dwFlags
);
7883 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
7884 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
7885 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7887 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, tests
[i
].world_matrix
);
7888 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
7890 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7891 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
7893 hr
= IDirect3DDevice2_BeginScene(device
);
7894 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
7896 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
,
7897 tests
[i
].quad
, 4, indices
, 6, 0);
7898 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
7900 hr
= IDirect3DDevice2_EndScene(device
);
7901 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
7903 color
= get_surface_color(rt
, 320, 240);
7904 ok(color
== tests
[i
].expected
, "%s has color 0x%08x.\n", tests
[i
].message
, color
);
7907 hr
= IDirect3DViewport2_DeleteLight(viewport
, light
);
7908 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#x.\n", hr
);
7909 IDirect3DLight_Release(light
);
7910 destroy_material(material
);
7911 destroy_viewport(device
, viewport
);
7912 IDirectDrawSurface2_Release(rt
);
7913 refcount
= IDirect3DDevice2_Release(device
);
7914 ok(!refcount
, "Device has %u references left.\n", refcount
);
7915 IDirect3D2_Release(d3d
);
7916 refcount
= IDirectDraw2_Release(ddraw
);
7917 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
7918 DestroyWindow(window
);
7921 static void test_specular_lighting(void)
7923 static const unsigned int vertices_side
= 5;
7924 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
7925 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
7926 static D3DMATRIX mat
=
7928 1.0f
, 0.0f
, 0.0f
, 0.0f
,
7929 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7930 0.0f
, 0.0f
, 1.0f
, 0.0f
,
7931 0.0f
, 0.0f
, 0.0f
, 1.0f
,
7933 static D3DLIGHT2 directional
=
7936 D3DLIGHT_DIRECTIONAL
,
7937 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7938 {{0.0f
}, {0.0f
}, {0.0f
}},
7939 {{0.0f
}, {0.0f
}, {1.0f
}},
7945 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7946 {{0.0f
}, {0.0f
}, {0.0f
}},
7947 {{0.0f
}, {0.0f
}, {0.0f
}},
7956 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7957 {{0.0f
}, {0.0f
}, {0.0f
}},
7958 {{0.0f
}, {0.0f
}, {1.0f
}},
7962 M_PI
/ 12.0f
, M_PI
/ 3.0f
7967 D3DLIGHT_PARALLELPOINT
,
7968 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7969 {{0.5f
}, {0.0f
}, {-1.0f
}},
7970 {{0.0f
}, {0.0f
}, {0.0f
}},
7976 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7977 {{-1.1f
}, {0.0f
}, {1.1f
}},
7978 {{0.0f
}, {0.0f
}, {0.0f
}},
7987 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7988 {{0.0f
}, {0.0f
}, {0.1f
}},
7989 {{0.0f
}, {0.0f
}, {0.0f
}},
7994 static const struct expected_color
7999 expected_directional_local
[] =
8001 {160, 120, 0x003c3c3c},
8002 {320, 120, 0x00717171},
8003 {480, 120, 0x003c3c3c},
8004 {160, 240, 0x00717171},
8005 {320, 240, 0x00ffffff},
8006 {480, 240, 0x00717171},
8007 {160, 360, 0x003c3c3c},
8008 {320, 360, 0x00717171},
8009 {480, 360, 0x003c3c3c},
8011 expected_point_local
[] =
8013 {160, 120, 0x00000000},
8014 {320, 120, 0x00090909},
8015 {480, 120, 0x00000000},
8016 {160, 240, 0x00090909},
8017 {320, 240, 0x00fafafa},
8018 {480, 240, 0x00090909},
8019 {160, 360, 0x00000000},
8020 {320, 360, 0x00090909},
8021 {480, 360, 0x00000000},
8023 expected_spot_local
[] =
8025 {160, 120, 0x00000000},
8026 {320, 120, 0x00020202},
8027 {480, 120, 0x00000000},
8028 {160, 240, 0x00020202},
8029 {320, 240, 0x00fafafa},
8030 {480, 240, 0x00020202},
8031 {160, 360, 0x00000000},
8032 {320, 360, 0x00020202},
8033 {480, 360, 0x00000000},
8035 expected_parallelpoint
[] =
8037 {160, 120, 0x00050505},
8038 {320, 120, 0x002c2c2c},
8039 {480, 120, 0x006e6e6e},
8040 {160, 240, 0x00090909},
8041 {320, 240, 0x00717171},
8042 {480, 240, 0x00ffffff},
8043 {160, 360, 0x00050505},
8044 {320, 360, 0x002c2c2c},
8045 {480, 360, 0x006e6e6e},
8047 expected_point_far
[] =
8049 {160, 120, 0x00000000},
8050 {320, 120, 0x00000000},
8051 {480, 120, 0x00000000},
8052 {160, 240, 0x00000000},
8053 {320, 240, 0x00ffffff},
8054 {480, 240, 0x00000000},
8055 {160, 360, 0x00000000},
8056 {320, 360, 0x00000000},
8057 {480, 360, 0x00000000},
8061 {160, 120, 0x00000000},
8062 {320, 120, 0x00000000},
8063 {480, 120, 0x00000000},
8064 {160, 240, 0x00000000},
8065 {320, 240, 0x00000000},
8066 {480, 240, 0x00000000},
8067 {160, 360, 0x00000000},
8068 {320, 360, 0x00000000},
8069 {480, 360, 0x00000000},
8074 float specular_power
;
8075 const struct expected_color
*expected
;
8076 unsigned int expected_count
;
8080 {&directional
, 30.0f
, expected_directional_local
, ARRAY_SIZE(expected_directional_local
)},
8081 {&point
, 30.0f
, expected_point_local
, ARRAY_SIZE(expected_point_local
)},
8082 {&spot
, 30.0f
, expected_spot_local
, ARRAY_SIZE(expected_spot_local
)},
8083 {¶llelpoint
, 30.0f
, expected_parallelpoint
, ARRAY_SIZE(expected_parallelpoint
)},
8084 {&point_side
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8085 {&point_far
, 1.0f
, expected_point_far
, ARRAY_SIZE(expected_point_far
)},
8086 {&directional
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8087 {&point
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8088 {&spot
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8089 {¶llelpoint
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8090 {&point_far
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8093 IDirect3DDevice2
*device
;
8094 IDirectDraw2
*ddraw
;
8095 IDirectDrawSurface
*rt
;
8096 IDirect3DViewport2
*viewport
;
8097 IDirect3DMaterial2
*material
, *background_material
;
8098 IDirect3DLight
*light
;
8099 D3DMATERIALHANDLE mat_handle
;
8104 unsigned int i
, j
, x
, y
;
8108 window
= create_window();
8109 ddraw
= create_ddraw();
8110 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8111 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8113 skip("Failed to create a 3D device, skipping test.\n");
8114 DestroyWindow(window
);
8118 quad
= HeapAlloc(GetProcessHeap(), 0, vertices_side
* vertices_side
* sizeof(*quad
));
8119 indices
= HeapAlloc(GetProcessHeap(), 0, indices_count
* sizeof(*indices
));
8120 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
8122 for (x
= 0; x
< vertices_side
; ++x
)
8124 U1(quad
[i
]).x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
8125 U2(quad
[i
]).y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
8126 U3(quad
[i
]).z
= 1.0f
;
8127 U4(quad
[i
]).nx
= 0.0f
;
8128 U5(quad
[i
]).ny
= 0.0f
;
8129 U6(quad
[i
]).nz
= -1.0f
;
8130 U7(quad
[i
]).tu
= 0.0f
;
8131 U8(quad
[i
++]).tv
= 0.0f
;
8134 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
8136 for (x
= 0; x
< (vertices_side
- 1); ++x
)
8138 indices
[i
++] = y
* vertices_side
+ x
+ 1;
8139 indices
[i
++] = y
* vertices_side
+ x
;
8140 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
8141 indices
[i
++] = y
* vertices_side
+ x
+ 1;
8142 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
8143 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
8147 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
8148 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
8150 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
8151 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
8153 viewport
= create_viewport(device
, 0, 0, 640, 480);
8154 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
8155 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
8157 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
8158 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
8159 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
8160 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
8161 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
8162 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
8163 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
8164 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
8165 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
8166 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
8168 background_material
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
8169 viewport_set_background(device
, viewport
, background_material
);
8171 hr
= IDirect3D2_CreateLight(d3d
, &light
, NULL
);
8172 ok(SUCCEEDED(hr
), "Failed to create a light object, hr %#x.\n", hr
);
8173 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
8174 ok(SUCCEEDED(hr
), "Failed to add a light to the viewport, hr %#x.\n", hr
);
8176 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
8177 ok(SUCCEEDED(hr
), "Failed to enable specular lighting, hr %#x.\n", hr
);
8179 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
8181 tests
[i
].light
->dwFlags
= D3DLIGHT_ACTIVE
;
8182 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)tests
[i
].light
);
8183 ok(SUCCEEDED(hr
), "Failed to set light, hr %#x.\n", hr
);
8185 material
= create_specular_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, tests
[i
].specular_power
);
8186 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
8187 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
8188 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
8189 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
8191 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8192 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8194 hr
= IDirect3DDevice2_BeginScene(device
);
8195 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8197 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
,
8198 quad
, vertices_side
* vertices_side
, indices
, indices_count
, 0);
8199 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8201 hr
= IDirect3DDevice2_EndScene(device
);
8202 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8204 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
8206 color
= get_surface_color(rt
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
8207 ok(compare_color(color
, tests
[i
].expected
[j
].color
, 1),
8208 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
8209 tests
[i
].expected
[j
].color
, tests
[i
].expected
[j
].x
,
8210 tests
[i
].expected
[j
].y
, color
, i
);
8213 destroy_material(material
);
8216 hr
= IDirect3DViewport2_DeleteLight(viewport
, light
);
8217 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#x.\n", hr
);
8218 IDirect3DLight_Release(light
);
8219 destroy_material(background_material
);
8220 destroy_viewport(device
, viewport
);
8221 IDirectDrawSurface2_Release(rt
);
8222 refcount
= IDirect3DDevice2_Release(device
);
8223 ok(!refcount
, "Device has %u references left.\n", refcount
);
8224 IDirect3D2_Release(d3d
);
8225 refcount
= IDirectDraw2_Release(ddraw
);
8226 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
8227 DestroyWindow(window
);
8228 HeapFree(GetProcessHeap(), 0, indices
);
8229 HeapFree(GetProcessHeap(), 0, quad
);
8232 static void test_palette_gdi(void)
8234 IDirectDrawSurface
*surface
, *primary
;
8235 DDSURFACEDESC surface_desc
;
8236 IDirectDraw2
*ddraw
;
8237 IDirectDrawPalette
*palette
, *palette2
;
8241 PALETTEENTRY palette_entries
[256];
8247 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
8248 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
8249 * not the point of this test. */
8250 static const RGBQUAD expected1
[] =
8252 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
8253 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
8255 static const RGBQUAD expected2
[] =
8257 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
8258 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
8260 static const RGBQUAD expected3
[] =
8262 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
8263 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
8265 HPALETTE ddraw_palette_handle
;
8266 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
8267 RGBQUAD rgbquad
[255];
8268 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
8270 window
= create_window();
8271 ddraw
= create_ddraw();
8272 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8273 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8274 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8276 memset(&surface_desc
, 0, sizeof(surface_desc
));
8277 surface_desc
.dwSize
= sizeof(surface_desc
);
8278 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8279 surface_desc
.dwWidth
= 16;
8280 surface_desc
.dwHeight
= 16;
8281 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8282 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
8283 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
8284 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
8285 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8286 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8288 /* Avoid colors from the Windows default palette. */
8289 memset(palette_entries
, 0, sizeof(palette_entries
));
8290 palette_entries
[1].peRed
= 0x01;
8291 palette_entries
[2].peGreen
= 0x02;
8292 palette_entries
[3].peBlue
= 0x03;
8293 palette_entries
[4].peRed
= 0x13;
8294 palette_entries
[4].peGreen
= 0x14;
8295 palette_entries
[4].peBlue
= 0x15;
8296 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8297 palette_entries
, &palette
, NULL
);
8298 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8300 /* If there is no palette assigned and the display mode is not 8 bpp, some
8301 * drivers refuse to create a DC while others allow it. If a DC is created,
8302 * the DIB color table is uninitialized and contains random colors. No error
8303 * is generated when trying to read pixels and random garbage is returned.
8305 * The most likely explanation is that if the driver creates a DC, it (or
8306 * the higher-level runtime) uses GetSystemPaletteEntries to find the
8307 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
8308 * contains uninitialized garbage. See comments below for the P8 case. */
8310 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
8311 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8312 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8313 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8314 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
8315 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
8316 "Got unexpected palette %p, expected %p.\n",
8317 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
8319 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8320 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8321 for (i
= 0; i
< ARRAY_SIZE(expected1
); i
++)
8323 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
8324 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8325 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8326 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
8328 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8330 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8331 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8332 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8335 /* Update the palette while the DC is in use. This does not modify the DC. */
8336 palette_entries
[4].peRed
= 0x23;
8337 palette_entries
[4].peGreen
= 0x24;
8338 palette_entries
[4].peBlue
= 0x25;
8339 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
8340 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#x.\n", hr
);
8342 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
8343 ok(i
== 1, "Expected count 1, got %u.\n", i
);
8344 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
8345 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8346 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
8347 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
8349 /* Neither does re-setting the palette. */
8350 hr
= IDirectDrawSurface_SetPalette(surface
, NULL
);
8351 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8352 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
8353 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8355 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
8356 ok(i
== 1, "Expected count 1, got %u.\n", i
);
8357 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
8358 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8359 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
8360 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
8362 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
8363 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8365 /* Refresh the DC. This updates the palette. */
8366 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8367 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8368 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8369 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8370 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8372 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8373 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8374 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8375 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8377 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8379 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8380 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8381 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8383 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
8384 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8386 refcount
= IDirectDrawSurface_Release(surface
);
8387 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8389 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
8390 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8391 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
8393 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
8394 IDirectDrawPalette_Release(palette
);
8395 IDirectDraw2_Release(ddraw
);
8396 DestroyWindow(window
);
8399 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
8401 memset(&surface_desc
, 0, sizeof(surface_desc
));
8402 surface_desc
.dwSize
= sizeof(surface_desc
);
8403 surface_desc
.dwFlags
= DDSD_CAPS
;
8404 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8405 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
8406 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8408 memset(&fx
, 0, sizeof(fx
));
8409 fx
.dwSize
= sizeof(fx
);
8410 U5(fx
).dwFillColor
= 3;
8411 SetRect(&r
, 0, 0, 319, 479);
8412 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8413 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
8414 SetRect(&r
, 320, 0, 639, 479);
8415 U5(fx
).dwFillColor
= 4;
8416 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8417 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
8419 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
8420 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8421 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
8422 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8424 color
= GetPixel(dc
, 160, 240);
8425 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
8426 color
= GetPixel(dc
, 480, 240);
8427 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
8429 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
8430 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
8431 "Got unexpected palette %p, expected %p.\n",
8432 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
8433 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
8435 /* The primary uses the system palette. In exclusive mode, the system palette matches
8436 * the ddraw palette attached to the primary, so the result is what you would expect
8437 * from a regular surface. Tests for the interaction between the ddraw palette and
8438 * the system palette are not included pending an application that depends on this.
8439 * The relation between those causes problems on Windows Vista and newer for games
8440 * like Age of Empires or StarCraft. Don't emulate it without a real need. */
8441 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8442 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8443 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8445 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8446 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8447 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8448 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8450 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8452 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8453 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8454 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8456 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
8457 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8459 memset(&surface_desc
, 0, sizeof(surface_desc
));
8460 surface_desc
.dwSize
= sizeof(surface_desc
);
8461 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8462 surface_desc
.dwWidth
= 16;
8463 surface_desc
.dwHeight
= 16;
8464 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8465 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8466 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8468 /* Here the offscreen surface appears to use the primary's palette,
8469 * but in all likelihood it is actually the system palette. */
8470 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8471 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8472 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8473 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8474 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8476 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8477 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8478 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8479 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8481 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8483 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8484 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8485 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8487 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
8488 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8490 /* On real hardware a change to the primary surface's palette applies immediately,
8491 * even on device contexts from offscreen surfaces that do not have their own
8492 * palette. On the testbot VMs this is not the case. Don't test this until we
8493 * know of an application that depends on this. */
8495 memset(palette_entries
, 0, sizeof(palette_entries
));
8496 palette_entries
[1].peBlue
= 0x40;
8497 palette_entries
[2].peRed
= 0x40;
8498 palette_entries
[3].peGreen
= 0x40;
8499 palette_entries
[4].peRed
= 0x12;
8500 palette_entries
[4].peGreen
= 0x34;
8501 palette_entries
[4].peBlue
= 0x56;
8502 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8503 palette_entries
, &palette2
, NULL
);
8504 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8505 hr
= IDirectDrawSurface_SetPalette(surface
, palette2
);
8506 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8508 /* A palette assigned to the offscreen surface overrides the primary / system
8510 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8511 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8512 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8513 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8514 for (i
= 0; i
< ARRAY_SIZE(expected3
); i
++)
8516 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
8517 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8518 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8519 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
8521 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8523 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8524 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8525 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8527 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
8528 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8530 refcount
= IDirectDrawSurface_Release(surface
);
8531 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8533 /* The Windows 8 testbot keeps extra references to the primary and
8534 * backbuffer while in 8 bpp mode. */
8535 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
8536 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
8538 refcount
= IDirectDrawSurface_Release(primary
);
8539 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8540 refcount
= IDirectDrawPalette_Release(palette2
);
8541 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8542 refcount
= IDirectDrawPalette_Release(palette
);
8543 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8544 refcount
= IDirectDraw2_Release(ddraw
);
8545 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8546 DestroyWindow(window
);
8549 static void test_palette_alpha(void)
8551 IDirectDrawSurface
*surface1
;
8552 IDirectDrawSurface2
*surface
;
8553 DDSURFACEDESC surface_desc
;
8554 IDirectDraw2
*ddraw
;
8555 IDirectDrawPalette
*palette
;
8559 PALETTEENTRY palette_entries
[256];
8564 BOOL attach_allowed
;
8569 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
8570 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
8571 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
8574 window
= create_window();
8575 ddraw
= create_ddraw();
8576 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8577 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
8579 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
8580 IDirectDraw2_Release(ddraw
);
8581 DestroyWindow(window
);
8584 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8585 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8587 memset(palette_entries
, 0, sizeof(palette_entries
));
8588 palette_entries
[1].peFlags
= 0x42;
8589 palette_entries
[2].peFlags
= 0xff;
8590 palette_entries
[3].peFlags
= 0x80;
8591 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
8592 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8594 memset(palette_entries
, 0x66, sizeof(palette_entries
));
8595 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
8596 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
8597 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8598 palette_entries
[0].peFlags
);
8599 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8600 palette_entries
[1].peFlags
);
8601 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
8602 palette_entries
[2].peFlags
);
8603 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
8604 palette_entries
[3].peFlags
);
8606 IDirectDrawPalette_Release(palette
);
8608 memset(palette_entries
, 0, sizeof(palette_entries
));
8609 palette_entries
[1].peFlags
= 0x42;
8610 palette_entries
[1].peRed
= 0xff;
8611 palette_entries
[2].peFlags
= 0xff;
8612 palette_entries
[3].peFlags
= 0x80;
8613 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
8614 palette_entries
, &palette
, NULL
);
8615 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8617 memset(palette_entries
, 0x66, sizeof(palette_entries
));
8618 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
8619 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
8620 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8621 palette_entries
[0].peFlags
);
8622 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8623 palette_entries
[1].peFlags
);
8624 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
8625 palette_entries
[2].peFlags
);
8626 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
8627 palette_entries
[3].peFlags
);
8629 for (i
= 0; i
< ARRAY_SIZE(test_data
); i
++)
8631 memset(&surface_desc
, 0, sizeof(surface_desc
));
8632 surface_desc
.dwSize
= sizeof(surface_desc
);
8633 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
8634 surface_desc
.dwWidth
= 128;
8635 surface_desc
.dwHeight
= 128;
8636 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
8637 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8638 ok(SUCCEEDED(hr
), "Failed to create %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
8639 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
8640 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr
);
8641 IDirectDrawSurface_Release(surface1
);
8643 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
8644 if (test_data
[i
].attach_allowed
)
8645 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
8647 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
8655 hr
= IDirectDrawSurface2_GetDC(surface
, &dc
);
8656 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_CANTCREATEDC
) /* Win2k testbot */,
8657 "Failed to get DC, hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
8660 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
8661 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
8662 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
8663 rgbquad
.rgbRed
, test_data
[i
].name
);
8664 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
8665 rgbquad
.rgbGreen
, test_data
[i
].name
);
8666 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
8667 rgbquad
.rgbBlue
, test_data
[i
].name
);
8668 ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
8669 rgbquad
.rgbReserved
, test_data
[i
].name
);
8670 hr
= IDirectDrawSurface2_ReleaseDC(surface
, dc
);
8671 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8674 IDirectDrawSurface2_Release(surface
);
8677 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
8678 memset(&surface_desc
, 0, sizeof(surface_desc
));
8679 surface_desc
.dwSize
= sizeof(surface_desc
);
8680 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8681 surface_desc
.dwWidth
= 128;
8682 surface_desc
.dwHeight
= 128;
8683 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8684 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
8685 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8686 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8687 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8688 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8689 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8690 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8691 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8692 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
8693 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr
);
8694 IDirectDrawSurface_Release(surface1
);
8696 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
8697 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
8698 IDirectDrawSurface2_Release(surface
);
8700 /* The Windows 8 testbot keeps extra references to the primary
8701 * while in 8 bpp mode. */
8702 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
8703 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
8705 refcount
= IDirectDrawPalette_Release(palette
);
8706 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8707 refcount
= IDirectDraw2_Release(ddraw
);
8708 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8709 DestroyWindow(window
);
8712 static void test_lost_device(void)
8714 IDirectDrawSurface
*sysmem_surface
, *vidmem_surface
;
8715 IDirectDrawSurface
*surface
, *back_buffer
;
8716 DDSURFACEDESC surface_desc
;
8717 HWND window1
, window2
;
8718 IDirectDraw2
*ddraw
;
8724 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8725 0, 0, 640, 480, 0, 0, 0, 0);
8726 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8727 0, 0, 640, 480, 0, 0, 0, 0);
8728 ddraw
= create_ddraw();
8729 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8730 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8731 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8733 memset(&surface_desc
, 0, sizeof(surface_desc
));
8734 surface_desc
.dwSize
= sizeof(surface_desc
);
8735 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8736 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8737 surface_desc
.dwBackBufferCount
= 1;
8738 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8739 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8741 memset(&surface_desc
, 0, sizeof(surface_desc
));
8742 surface_desc
.dwSize
= sizeof(surface_desc
);
8743 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8744 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
8745 surface_desc
.dwWidth
= 100;
8746 surface_desc
.dwHeight
= 100;
8747 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
8748 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8750 memset(&surface_desc
, 0, sizeof(surface_desc
));
8751 surface_desc
.dwSize
= sizeof(surface_desc
);
8752 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8753 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
;
8754 surface_desc
.dwWidth
= 64;
8755 surface_desc
.dwHeight
= 64;
8756 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
8757 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8758 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8759 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8760 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8761 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8762 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &vidmem_surface
, NULL
)))
8764 skip("Failed to create video memory surface, skipping related tests.\n");
8765 vidmem_surface
= NULL
;
8768 hr
= IDirectDrawSurface_IsLost(surface
);
8769 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8770 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8771 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8772 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8773 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8776 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8777 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8780 ret
= SetForegroundWindow(GetDesktopWindow());
8781 ok(ret
, "Failed to set foreground window.\n");
8782 hr
= IDirectDrawSurface_IsLost(surface
);
8783 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8784 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8785 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8786 hr
= IDirectDrawSurface_Restore(surface
);
8787 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
8788 hr
= IDirectDrawSurface_IsLost(surface
);
8789 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8790 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8791 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8792 hr
= IDirectDrawSurface_Restore(sysmem_surface
);
8793 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8794 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8795 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8798 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8799 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8800 hr
= IDirectDrawSurface_Restore(vidmem_surface
);
8801 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
8802 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8803 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8806 ret
= SetForegroundWindow(window1
);
8807 ok(ret
, "Failed to set foreground window.\n");
8808 hr
= IDirectDrawSurface_IsLost(surface
);
8809 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8810 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8811 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8812 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8813 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8816 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8817 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8820 hr
= restore_surfaces(ddraw
);
8821 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8822 hr
= IDirectDrawSurface_IsLost(surface
);
8823 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8824 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8825 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8826 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8827 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8830 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8831 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8834 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
8835 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8836 hr
= IDirectDrawSurface_IsLost(surface
);
8837 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8838 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8839 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8840 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8841 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8844 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8845 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8848 /* Trying to restore the primary will crash, probably because flippable
8849 * surfaces can't exist in DDSCL_NORMAL. */
8850 IDirectDrawSurface_Release(surface
);
8851 memset(&surface_desc
, 0, sizeof(surface_desc
));
8852 surface_desc
.dwSize
= sizeof(surface_desc
);
8853 surface_desc
.dwFlags
= DDSD_CAPS
;
8854 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8855 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8856 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8857 hr
= restore_surfaces(ddraw
);
8858 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8860 hr
= IDirectDrawSurface_IsLost(surface
);
8861 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8863 ret
= SetForegroundWindow(GetDesktopWindow());
8864 ok(ret
, "Failed to set foreground window.\n");
8865 hr
= IDirectDrawSurface_IsLost(surface
);
8866 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8867 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8868 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8871 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8872 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8875 ret
= SetForegroundWindow(window1
);
8876 ok(ret
, "Failed to set foreground window.\n");
8877 hr
= IDirectDrawSurface_IsLost(surface
);
8878 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8879 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8880 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8883 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8884 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8887 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8888 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8889 hr
= IDirectDrawSurface_IsLost(surface
);
8890 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8891 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8892 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8895 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8896 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8899 hr
= restore_surfaces(ddraw
);
8900 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8901 hr
= IDirectDrawSurface_IsLost(surface
);
8902 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8903 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8904 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8907 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8908 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8911 IDirectDrawSurface_Release(surface
);
8912 memset(&surface_desc
, 0, sizeof(surface_desc
));
8913 surface_desc
.dwSize
= sizeof(surface_desc
);
8914 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8915 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8916 surface_desc
.dwBackBufferCount
= 1;
8917 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8918 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8920 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8921 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8922 hr
= IDirectDrawSurface_IsLost(surface
);
8923 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8924 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8925 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8926 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8927 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8930 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8931 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8934 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
8935 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8936 hr
= IDirectDrawSurface_IsLost(surface
);
8937 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8938 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8939 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8940 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8941 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8944 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8945 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8948 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
8949 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8950 hr
= IDirectDrawSurface_IsLost(surface
);
8951 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8952 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8953 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8954 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8955 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8958 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8959 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8962 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
8963 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8964 hr
= IDirectDrawSurface_IsLost(surface
);
8965 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8966 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8967 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8968 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8969 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8972 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8973 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8976 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
8977 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8978 hr
= IDirectDrawSurface_IsLost(surface
);
8979 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8980 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8981 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8982 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8983 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8986 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8987 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8990 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8991 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8992 hr
= IDirectDrawSurface_IsLost(surface
);
8993 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8994 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8995 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8996 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8997 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9000 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9001 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9004 memset(&caps
, 0, sizeof(caps
));
9005 caps
.dwCaps
= DDSCAPS_FLIP
;
9007 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &back_buffer
);
9008 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9009 hr
= IDirectDrawSurface_Restore(surface
);
9010 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9011 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &back_buffer
);
9012 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9013 hr
= IDirectDrawSurface_IsLost(back_buffer
);
9014 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9015 IDirectDrawSurface_Release(back_buffer
);
9018 IDirectDrawSurface_Release(vidmem_surface
);
9019 IDirectDrawSurface_Release(sysmem_surface
);
9020 IDirectDrawSurface_Release(surface
);
9021 refcount
= IDirectDraw2_Release(ddraw
);
9022 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9023 DestroyWindow(window2
);
9024 DestroyWindow(window1
);
9027 static void test_surface_desc_lock(void)
9029 IDirectDrawSurface
*surface
;
9030 DDSURFACEDESC surface_desc
;
9031 IDirectDraw2
*ddraw
;
9036 window
= create_window();
9037 ddraw
= create_ddraw();
9038 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9039 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9040 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9042 memset(&surface_desc
, 0, sizeof(surface_desc
));
9043 surface_desc
.dwSize
= sizeof(surface_desc
);
9044 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
9045 surface_desc
.dwWidth
= 16;
9046 surface_desc
.dwHeight
= 16;
9047 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9048 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9049 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9051 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9052 surface_desc
.dwSize
= sizeof(surface_desc
);
9053 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
9054 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9055 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9057 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9058 surface_desc
.dwSize
= sizeof(surface_desc
);
9059 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
9060 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
9061 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9062 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9063 surface_desc
.dwSize
= sizeof(surface_desc
);
9064 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
9065 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9066 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9067 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9068 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
9070 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9071 surface_desc
.dwSize
= sizeof(surface_desc
);
9072 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
9073 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9074 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9076 IDirectDrawSurface_Release(surface
);
9077 refcount
= IDirectDraw2_Release(ddraw
);
9078 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9079 DestroyWindow(window
);
9082 static void test_texturemapblend(void)
9087 static RECT rect
= {0, 0, 64, 128};
9088 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9090 IDirectDrawSurface
*surface
, *rt
;
9091 IDirect3DTexture2
*texture
;
9092 D3DTEXTUREHANDLE texture_handle
;
9094 IDirectDraw2
*ddraw
;
9095 IDirect3DDevice2
*device
;
9096 IDirect3DMaterial2
*material
;
9097 IDirect3DViewport2
*viewport
;
9101 static D3DTLVERTEX test1_quads
[] =
9103 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {0.0f
}},
9104 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {1.0f
}},
9105 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {0.0f
}},
9106 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {1.0f
}},
9107 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {0.0f
}},
9108 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {1.0f
}},
9109 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {0.0f
}},
9110 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {1.0f
}},
9114 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {0.0f
}},
9115 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {1.0f
}},
9116 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {0.0f
}},
9117 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {1.0f
}},
9118 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {0.0f
}},
9119 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {1.0f
}},
9120 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {0.0f
}},
9121 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {1.0f
}},
9124 window
= create_window();
9125 ddraw
= create_ddraw();
9126 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9127 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9129 skip("Failed to create a 3D device, skipping test.\n");
9130 DestroyWindow(window
);
9131 IDirectDraw2_Release(ddraw
);
9135 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
9136 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
9138 material
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
9139 viewport
= create_viewport(device
, 0, 0, 640, 480);
9140 viewport_set_background(device
, viewport
, material
);
9141 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
9142 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
9144 /* Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel.
9146 * The vertex alpha is completely ignored in this case, so case 1 and 2 combined are not
9147 * a D3DTOP_MODULATE with texture alpha = 0xff in case 2 (no alpha in texture). */
9148 memset(&ddsd
, 0, sizeof(ddsd
));
9149 ddsd
.dwSize
= sizeof(ddsd
);
9150 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9151 ddsd
.dwHeight
= 128;
9153 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9154 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
9155 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9156 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9157 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9158 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9159 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9160 U5(ddsd
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
9161 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
9162 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9164 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9165 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9166 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
9167 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
9168 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
9169 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9171 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9172 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9174 memset(&fx
, 0, sizeof(fx
));
9175 fx
.dwSize
= sizeof(fx
);
9176 U5(fx
).dwFillColor
= 0xff0000ff;
9177 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9178 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9179 U5(fx
).dwFillColor
= 0x800000ff;
9180 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9181 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9183 /* Note that the ddraw1 version of this test runs tests 1-3 with D3DRENDERSTATE_COLORKEYENABLE
9184 * enabled, whereas this version only runs test 4 with color keying on. Because no color key
9185 * is set on the texture this should not result in different behavior. */
9186 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
9187 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9188 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
9189 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9190 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
9191 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9192 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
9193 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9194 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
9195 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9196 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
9197 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9199 hr
= IDirect3DDevice2_BeginScene(device
);
9200 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9201 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
9202 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9203 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
9204 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9205 hr
= IDirect3DDevice2_EndScene(device
);
9206 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9208 color
= get_surface_color(rt
, 5, 5);
9209 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9210 color
= get_surface_color(rt
, 400, 5);
9211 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9212 color
= get_surface_color(rt
, 5, 245);
9213 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9214 color
= get_surface_color(rt
, 400, 245);
9215 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9217 IDirect3DTexture2_Release(texture
);
9218 ref
= IDirectDrawSurface_Release(surface
);
9219 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
9221 /* Test alpha with texture that has no alpha channel - alpha should be taken from diffuse vertex color. */
9222 memset(&ddsd
, 0, sizeof(ddsd
));
9223 ddsd
.dwSize
= sizeof(ddsd
);
9224 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9225 ddsd
.dwHeight
= 128;
9227 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9228 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
9229 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9230 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9231 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9232 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9233 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9235 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
9236 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9238 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9239 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9240 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
9241 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
9242 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
9243 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9245 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9246 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9248 U5(fx
).dwFillColor
= 0xff0000ff;
9249 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9250 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9251 U5(fx
).dwFillColor
= 0x800000ff;
9252 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9253 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9255 hr
= IDirect3DDevice2_BeginScene(device
);
9256 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9257 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
9258 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9259 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
9260 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9261 hr
= IDirect3DDevice2_EndScene(device
);
9262 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9264 color
= get_surface_color(rt
, 5, 5);
9265 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9266 color
= get_surface_color(rt
, 400, 5);
9267 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9268 color
= get_surface_color(rt
, 5, 245);
9269 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9270 color
= get_surface_color(rt
, 400, 245);
9271 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9273 IDirect3DTexture2_Release(texture
);
9274 ref
= IDirectDrawSurface_Release(surface
);
9275 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
9277 /* Test RGB - should multiply color components from diffuse vertex color and texture. */
9278 memset(&ddsd
, 0, sizeof(ddsd
));
9279 ddsd
.dwSize
= sizeof(ddsd
);
9280 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9281 ddsd
.dwHeight
= 128;
9283 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9284 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
9285 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9286 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9287 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9288 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9289 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9290 U5(ddsd
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
9291 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
9292 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9294 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9295 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9296 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
9297 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
9298 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
9299 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9301 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9302 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9304 U5(fx
).dwFillColor
= 0x00ffffff;
9305 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9306 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9307 U5(fx
).dwFillColor
= 0x00ffff80;
9308 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9309 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9311 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
9312 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9314 hr
= IDirect3DDevice2_BeginScene(device
);
9315 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9316 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test2_quads
[0], 4, 0);
9317 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9318 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test2_quads
[4], 4, 0);
9319 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9320 hr
= IDirect3DDevice2_EndScene(device
);
9321 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9323 color
= get_surface_color(rt
, 5, 5);
9324 ok(compare_color(color
, 0x00ff0040, 2), "Got unexpected color 0x%08x.\n", color
);
9325 color
= get_surface_color(rt
, 400, 5);
9326 ok(compare_color(color
, 0x00ff0080, 2), "Got unexpected color 0x%08x.\n", color
);
9327 color
= get_surface_color(rt
, 5, 245);
9328 ok(compare_color(color
, 0x00800080, 2), "Got unexpected color 0x%08x.\n", color
);
9329 color
= get_surface_color(rt
, 400, 245);
9330 ok(compare_color(color
, 0x008000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9332 IDirect3DTexture2_Release(texture
);
9333 ref
= IDirectDrawSurface_Release(surface
);
9334 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
9336 /* Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere). */
9337 memset(&ddsd
, 0, sizeof(ddsd
));
9338 ddsd
.dwSize
= sizeof(ddsd
);
9339 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9340 ddsd
.dwHeight
= 128;
9342 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9343 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
9344 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9345 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 16;
9346 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
9347 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
9348 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
9350 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
9351 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9353 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9354 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9355 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
9356 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
9357 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
9358 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9360 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9361 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9363 U5(fx
).dwFillColor
= 0xf800;
9364 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9365 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9366 U5(fx
).dwFillColor
= 0x001f;
9367 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9368 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9370 ckey
.dwColorSpaceLowValue
= 0x001f;
9371 ckey
.dwColorSpaceHighValue
= 0x001f;
9372 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9373 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
9375 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
9376 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9377 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
9378 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9380 hr
= IDirect3DDevice2_BeginScene(device
);
9381 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9382 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
9383 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9384 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
9385 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9386 hr
= IDirect3DDevice2_EndScene(device
);
9387 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9389 color
= get_surface_color(rt
, 5, 5);
9390 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
9391 color
= get_surface_color(rt
, 400, 5);
9392 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
9393 color
= get_surface_color(rt
, 5, 245);
9394 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
9395 color
= get_surface_color(rt
, 400, 245);
9396 ok(compare_color(color
, 0x00800000, 2), "Got unexpected color 0x%08x.\n", color
);
9398 IDirect3DTexture2_Release(texture
);
9399 ref
= IDirectDrawSurface_Release(surface
);
9400 ok(ref
== 0, "Surface not properly released, refcount %u.\n", ref
);
9402 destroy_viewport(device
, viewport
);
9403 ref
= IDirect3DMaterial2_Release(material
);
9404 ok(ref
== 0, "Material not properly released, refcount %u.\n", ref
);
9405 IDirectDrawSurface_Release(rt
);
9406 IDirect3DDevice2_Release(device
);
9407 ref
= IDirectDraw2_Release(ddraw
);
9408 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
9409 DestroyWindow(window
);
9412 static void test_viewport_clear_rect(void)
9415 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9416 static D3DRECT clear_rect2
= {{90}, {90}, {110}, {110}};
9417 IDirectDrawSurface
*rt
;
9419 IDirectDraw2
*ddraw
;
9420 IDirect3DDevice2
*device
;
9421 IDirect3DMaterial2
*red
, *green
;
9422 IDirect3DViewport2
*viewport
, *viewport2
;
9426 window
= create_window();
9427 ddraw
= create_ddraw();
9428 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9429 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9431 skip("Failed to create a 3D device, skipping test.\n");
9432 DestroyWindow(window
);
9433 IDirectDraw2_Release(ddraw
);
9437 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
9438 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
9440 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
9441 viewport
= create_viewport(device
, 0, 0, 640, 480);
9442 viewport_set_background(device
, viewport
, red
);
9443 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9444 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
9446 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
9447 viewport2
= create_viewport(device
, 100, 100, 20, 20);
9448 viewport_set_background(device
, viewport2
, green
);
9449 hr
= IDirect3DViewport2_Clear(viewport2
, 1, &clear_rect2
, D3DCLEAR_TARGET
);
9450 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
9452 color
= get_surface_color(rt
, 85, 85); /* Outside both. */
9453 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9454 color
= get_surface_color(rt
, 95, 95); /* Outside vp, inside rect. */
9455 /* AMD GPUs ignore the viewport dimensions and only care about the rectangle. */
9456 ok(compare_color(color
, 0x00ff0000, 1) || broken(compare_color(color
, 0x0000ff00, 1)),
9457 "Got unexpected color 0x%08x.\n", color
);
9458 color
= get_surface_color(rt
, 105, 105); /* Inside both. */
9459 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
9460 color
= get_surface_color(rt
, 115, 115); /* Inside vp, outside rect. */
9461 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9462 color
= get_surface_color(rt
, 125, 125); /* Outside both. */
9463 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9465 destroy_viewport(device
, viewport2
);
9466 destroy_material(green
);
9467 destroy_viewport(device
, viewport
);
9468 destroy_material(red
);
9469 IDirectDrawSurface_Release(rt
);
9470 IDirect3DDevice2_Release(device
);
9471 ref
= IDirectDraw2_Release(ddraw
);
9472 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
9473 DestroyWindow(window
);
9476 static void test_color_fill(void)
9479 IDirect3DDevice2
*device
;
9480 IDirectDraw2
*ddraw
;
9481 IDirectDrawSurface
*surface
, *surface2
;
9482 DDSURFACEDESC surface_desc
;
9488 RECT rect
= {5, 5, 7, 7};
9490 DWORD num_fourcc_codes
, *fourcc_codes
;
9492 BOOL support_uyvy
= FALSE
, support_yuy2
= FALSE
;
9496 HRESULT colorfill_hr
, depthfill_hr
;
9501 DDPIXELFORMAT format
;
9506 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9507 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
9509 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9510 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9514 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
9515 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
9517 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9518 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9522 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
9523 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
9525 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9526 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9530 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
9531 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
9533 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9534 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9538 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
,
9539 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0xdeadbeef, TRUE
,
9540 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
9543 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
9544 * different afterwards. DX9+ GPUs set one of the two luminance values
9545 * in each block, but AMD and Nvidia GPUs disagree on which luminance
9546 * value they set. r200 (dx8) just sets the entire block to the clear
9548 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9549 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
9551 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
9552 {0}, {0}, {0}, {0}, {0}
9556 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9557 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
9559 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
9560 {0}, {0}, {0}, {0}, {0}
9564 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
9565 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
9567 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
9568 {0}, {0}, {0}, {0}, {0}
9572 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
9573 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
9575 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
9576 {0}, {0}, {0}, {0}, {0}
9580 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
9581 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
9583 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
9584 {0}, {0}, {0}, {0}, {0}
9588 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
9589 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
9591 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
9592 {0}, {0}, {0}, {0}, {0}
9596 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
9597 * surface works, presumably because it is handled by the runtime instead of
9599 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9600 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
9602 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
9603 {8}, {0}, {0}, {0}, {0}
9607 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
9608 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
9610 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
9611 {8}, {0}, {0}, {0}, {0}
9623 {SRCCOPY
, "SRCCOPY", DD_OK
},
9624 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
9625 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
9626 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
9627 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
9628 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
9629 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
9630 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
9631 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
9632 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
9633 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
9634 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
9635 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
9636 {BLACKNESS
, "BLACKNESS", DD_OK
},
9637 {WHITENESS
, "WHITENESS", DD_OK
},
9638 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
9641 window
= create_window();
9642 ddraw
= create_ddraw();
9643 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9644 is_warp
= ddraw_is_warp(ddraw
);
9645 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9647 skip("Failed to create a 3D device, skipping test.\n");
9648 DestroyWindow(window
);
9649 IDirectDraw2_Release(ddraw
);
9653 hr
= IDirectDraw2_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
9654 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
9655 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
9656 num_fourcc_codes
* sizeof(*fourcc_codes
));
9659 hr
= IDirectDraw2_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
9660 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
9661 for (i
= 0; i
< num_fourcc_codes
; i
++)
9663 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
9664 support_yuy2
= TRUE
;
9665 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
9666 support_uyvy
= TRUE
;
9668 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
9670 memset(&hal_caps
, 0, sizeof(hal_caps
));
9671 hal_caps
.dwSize
= sizeof(hal_caps
);
9672 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
9673 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
9675 if ((!support_yuy2
&& !support_uyvy
) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
9676 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
9678 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
9680 DWORD expected_broken
= tests
[i
].result
;
9681 DWORD mask
= 0xffffffffu
;
9683 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
9684 memset(&fx
, 0, sizeof(fx
));
9685 fx
.dwSize
= sizeof(fx
);
9686 U5(fx
).dwFillColor
= 0xdeadbeef;
9688 memset(&surface_desc
, 0, sizeof(surface_desc
));
9689 surface_desc
.dwSize
= sizeof(surface_desc
);
9690 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9691 surface_desc
.dwWidth
= 64;
9692 surface_desc
.dwHeight
= 64;
9693 surface_desc
.ddpfPixelFormat
= tests
[i
].format
;
9694 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
9696 if (tests
[i
].caps
& DDSCAPS_TEXTURE
)
9698 struct format_support_check check
= {&tests
[i
].format
, FALSE
};
9699 hr
= IDirect3DDevice2_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
9700 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
9701 if (!check
.supported
)
9705 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !support_yuy2
)
9707 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !support_uyvy
)
9709 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
9712 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
9714 surface_desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
9715 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
9716 U2(surface_desc
).dwZBufferBitDepth
= get_device_z_depth(device
);
9717 mask
>>= (32 - U2(surface_desc
).dwZBufferBitDepth
);
9718 /* Some drivers seem to convert depth values incorrectly or not at
9719 * all. Affects at least AMD PALM, 8.17.10.1247. */
9720 if (tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
9725 expected
= tests
[i
].result
& mask
;
9726 f
= ceilf(logf(expected
+ 1.0f
) / logf(2.0f
));
9727 g
= (f
+ 1.0f
) / 2.0f
;
9729 expected_broken
= (expected
/ exp2f(f
) - g
) * 256;
9730 expected_broken
*= 0x01010101;
9734 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9735 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9737 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9738 todo_wine_if (tests
[i
].format
.dwFourCC
)
9739 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
9740 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
9742 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9743 todo_wine_if (tests
[i
].format
.dwFourCC
)
9744 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
9745 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
9747 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9749 memset(&surface_desc
, 0, sizeof(surface_desc
));
9750 surface_desc
.dwSize
= sizeof(surface_desc
);
9751 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9752 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9753 color
= surface_desc
.lpSurface
;
9754 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
9755 *color
, tests
[i
].result
, tests
[i
].name
);
9756 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9757 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9760 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9761 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
9762 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
9763 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9764 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
9765 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
9767 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9769 memset(&surface_desc
, 0, sizeof(surface_desc
));
9770 surface_desc
.dwSize
= sizeof(surface_desc
);
9771 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9772 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9773 color
= surface_desc
.lpSurface
;
9774 todo_wine_if(tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
&& U2(surface_desc
).dwZBufferBitDepth
!= 16)
9775 ok((*color
& mask
) == (tests
[i
].result
& mask
) || broken((*color
& mask
) == (expected_broken
& mask
))
9776 || broken(is_warp
&& (*color
& mask
) == (~0u & mask
)) /* Windows 8+ testbot. */,
9777 "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
9778 *color
& mask
, tests
[i
].result
& mask
, tests
[i
].name
);
9779 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9780 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9783 U5(fx
).dwFillColor
= 0xdeadbeef;
9784 fx
.dwROP
= BLACKNESS
;
9785 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9786 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
9787 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
9788 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
9789 U5(fx
).dwFillColor
, tests
[i
].name
);
9791 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9793 memset(&surface_desc
, 0, sizeof(surface_desc
));
9794 surface_desc
.dwSize
= sizeof(surface_desc
);
9795 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9796 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9797 color
= surface_desc
.lpSurface
;
9798 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
9799 *color
, tests
[i
].name
);
9800 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9801 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9804 fx
.dwROP
= WHITENESS
;
9805 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9806 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
9807 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
9808 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
9809 U5(fx
).dwFillColor
, tests
[i
].name
);
9811 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9813 memset(&surface_desc
, 0, sizeof(surface_desc
));
9814 surface_desc
.dwSize
= sizeof(surface_desc
);
9815 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9816 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9817 color
= surface_desc
.lpSurface
;
9818 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
9819 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
9820 *color
, tests
[i
].name
);
9821 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9822 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9825 IDirectDrawSurface_Release(surface
);
9828 memset(&fx
, 0, sizeof(fx
));
9829 fx
.dwSize
= sizeof(fx
);
9830 U5(fx
).dwFillColor
= 0xdeadbeef;
9831 fx
.dwROP
= WHITENESS
;
9833 memset(&surface_desc
, 0, sizeof(surface_desc
));
9834 surface_desc
.dwSize
= sizeof(surface_desc
);
9835 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9836 surface_desc
.dwWidth
= 64;
9837 surface_desc
.dwHeight
= 64;
9838 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
9839 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9840 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9841 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9842 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9843 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9844 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
9845 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9846 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9847 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
9848 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9851 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
9852 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9853 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
9854 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9856 /* Unused source rectangle. */
9857 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9858 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9859 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9860 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9862 /* Unused source surface. */
9863 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9864 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9865 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9866 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9867 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9868 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9869 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9870 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9872 /* Inverted destination or source rectangle. */
9873 SetRect(&rect
, 5, 7, 7, 5);
9874 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9875 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9876 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9877 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9878 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9879 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9880 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9881 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9882 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9883 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9885 /* Negative rectangle. */
9886 SetRect(&rect
, -1, -1, 5, 5);
9887 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9888 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9889 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9890 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9891 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9892 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9893 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9894 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9895 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9896 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9898 /* Out of bounds rectangle. */
9899 SetRect(&rect
, 0, 0, 65, 65);
9900 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9901 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9902 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9903 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9905 /* Combine multiple flags. */
9906 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9907 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9908 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9909 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9910 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9911 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9913 for (i
= 0; i
< ARRAY_SIZE(rops
); i
++)
9915 fx
.dwROP
= rops
[i
].rop
;
9916 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9917 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#x for rop %s.\n", hr
, rops
[i
].name
);
9920 IDirectDrawSurface_Release(surface2
);
9921 IDirectDrawSurface_Release(surface
);
9923 memset(&surface_desc
, 0, sizeof(surface_desc
));
9924 surface_desc
.dwSize
= sizeof(surface_desc
);
9925 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_ZBUFFERBITDEPTH
;
9926 surface_desc
.dwWidth
= 64;
9927 surface_desc
.dwHeight
= 64;
9928 U2(surface_desc
).dwZBufferBitDepth
= get_device_z_depth(device
);
9929 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
9930 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9931 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9932 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
9933 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9936 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
9937 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9939 /* Unused source rectangle. */
9940 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9941 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9943 /* Unused source surface. */
9944 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9945 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9946 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9947 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9949 /* Inverted destination or source rectangle. */
9950 SetRect(&rect
, 5, 7, 7, 5);
9951 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9952 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9953 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9954 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9955 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9956 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9957 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9958 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9960 /* Negative rectangle. */
9961 SetRect(&rect
, -1, -1, 5, 5);
9962 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9963 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9964 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9965 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
9966 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9967 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9968 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9969 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9971 /* Out of bounds rectangle. */
9972 SetRect(&rect
, 0, 0, 65, 65);
9973 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9974 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
9976 /* Combine multiple flags. */
9977 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9978 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
9980 IDirectDrawSurface_Release(surface2
);
9981 IDirectDrawSurface_Release(surface
);
9984 IDirect3DDevice2_Release(device
);
9985 refcount
= IDirectDraw2_Release(ddraw
);
9986 ok(refcount
== 0, "Ddraw object not properly released, refcount %u.\n", refcount
);
9987 DestroyWindow(window
);
9990 static void test_colorkey_precision(void)
9992 static D3DLVERTEX quad
[] =
9994 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {0.0f
}, {0.0f
}},
9995 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {0.0f
}, {1.0f
}},
9996 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {1.0f
}, {0.0f
}},
9997 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {1.0f
}, {1.0f
}},
9999 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10000 IDirect3DDevice2
*device
;
10001 IDirectDraw2
*ddraw
;
10002 IDirectDrawSurface
*rt
;
10003 IDirect3DViewport2
*viewport
;
10006 IDirectDrawSurface
*src
, *dst
, *texture
;
10007 D3DTEXTUREHANDLE handle
;
10008 IDirect3DTexture2
*d3d_texture
;
10009 IDirect3DMaterial2
*green
;
10010 DDSURFACEDESC surface_desc
, lock_desc
;
10016 DWORD data
[4] = {0}, color_mask
;
10017 BOOL is_nvidia
, is_warp
;
10018 static const struct
10020 unsigned int max
, shift
, bpp
, clear
;
10028 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
10030 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10031 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
10036 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
10038 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10039 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
10044 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
10046 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10047 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
10052 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
10054 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
10055 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
10060 window
= create_window();
10061 ddraw
= create_ddraw();
10062 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10063 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10065 skip("Failed to create a 3D device, skipping test.\n");
10066 DestroyWindow(window
);
10067 IDirectDraw2_Release(ddraw
);
10070 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
10071 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10073 is_nvidia
= ddraw_is_nvidia(ddraw
);
10074 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
10075 * (color key doesn't match although the values are equal), and a false
10076 * positive when the color key is 0 and the texture contains the value 1.
10077 * I don't want to mark this broken unconditionally since this would
10078 * essentially disable the test on Windows. Also on random occasions
10079 * 254 == 255 and 255 != 255.*/
10080 is_warp
= ddraw_is_warp(ddraw
);
10082 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
10083 viewport
= create_viewport(device
, 0, 0, 640, 480);
10084 viewport_set_background(device
, viewport
, green
);
10085 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
10086 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
10088 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
10089 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
10090 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
10091 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
10092 /* There's no way to ignore the texture color in d3d2, so multiply the texture color
10093 * with a black vertex color. */
10094 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATEALPHA
);
10095 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10097 memset(&fx
, 0, sizeof(fx
));
10098 fx
.dwSize
= sizeof(fx
);
10099 memset(&lock_desc
, 0, sizeof(lock_desc
));
10100 lock_desc
.dwSize
= sizeof(lock_desc
);
10102 for (t
= 0; t
< ARRAY_SIZE(tests
); ++t
)
10104 if (is_nvidia
&& tests
[t
].skip_nv
)
10106 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
10110 memset(&surface_desc
, 0, sizeof(surface_desc
));
10111 surface_desc
.dwSize
= sizeof(surface_desc
);
10112 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10113 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10114 surface_desc
.dwWidth
= 4;
10115 surface_desc
.dwHeight
= 1;
10116 surface_desc
.ddpfPixelFormat
= tests
[t
].fmt
;
10117 /* Windows XP (at least with the r200 driver, other drivers untested) produces
10118 * garbage when doing color keyed texture->texture blits. */
10119 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
10120 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10121 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
10122 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10124 U5(fx
).dwFillColor
= tests
[t
].clear
;
10125 /* On the w8 testbot (WARP driver) the blit result has different values in the
10127 color_mask
= U2(tests
[t
].fmt
).dwRBitMask
10128 | U3(tests
[t
].fmt
).dwGBitMask
10129 | U4(tests
[t
].fmt
).dwBBitMask
;
10131 for (c
= 0; c
<= tests
[t
].max
; ++c
)
10133 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
10134 * texture after it has been set once... */
10135 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
10136 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10137 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
10138 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
10139 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
10140 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10142 hr
= IDirectDrawSurface4_QueryInterface(texture
, &IID_IDirect3DTexture2
, (void **)&d3d_texture
);
10143 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
10144 hr
= IDirect3DTexture2_GetHandle(d3d_texture
, device
, &handle
);
10145 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
10146 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, handle
);
10147 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
10148 IDirect3DTexture2_Release(d3d_texture
);
10150 hr
= IDirectDrawSurface_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10151 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
10153 hr
= IDirectDrawSurface_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
10154 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10155 switch (tests
[t
].bpp
)
10158 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
10159 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
10160 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
10161 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
10165 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
10166 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
10167 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
10168 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
10171 hr
= IDirectDrawSurface_Unlock(src
, 0);
10172 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10173 hr
= IDirectDrawSurface_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
10174 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
10176 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
10177 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
10178 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
10179 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
10181 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
10182 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
10184 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
10185 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
10186 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10187 switch (tests
[t
].bpp
)
10190 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
10191 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
10192 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
10193 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
10197 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
10198 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
10199 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
10200 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
10203 hr
= IDirectDrawSurface_Unlock(dst
, 0);
10204 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10208 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10209 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
10211 if (data
[3] == tests
[t
].clear
)
10213 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
10214 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
10215 * even when a different surface is used. The blit itself doesn't draw anything,
10216 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
10217 * never be masked out by the key.
10219 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
10220 * test is disabled entirely.
10222 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
10223 * terrible on WARP. */
10224 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
10225 IDirectDrawSurface_Release(texture
);
10226 IDirectDrawSurface_Release(src
);
10227 IDirectDrawSurface_Release(dst
);
10232 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10233 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
10235 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10236 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
10238 if (c
== tests
[t
].max
)
10239 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10240 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
10242 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10243 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
10245 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10246 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10248 hr
= IDirect3DDevice2_BeginScene(device
);
10249 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10250 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
10251 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10252 hr
= IDirect3DDevice2_EndScene(device
);
10253 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10255 color
= get_surface_color(rt
, 80, 240);
10257 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10258 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10259 color
, tests
[t
].name
, c
);
10261 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
10262 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10263 color
, tests
[t
].name
, c
);
10265 color
= get_surface_color(rt
, 240, 240);
10266 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10267 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10268 color
, tests
[t
].name
, c
);
10270 color
= get_surface_color(rt
, 400, 240);
10271 if (c
== tests
[t
].max
)
10272 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10273 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10274 color
, tests
[t
].name
, c
);
10276 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
10277 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10278 color
, tests
[t
].name
, c
);
10280 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
10281 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#x.\n", hr
);
10282 IDirectDrawSurface_Release(texture
);
10284 IDirectDrawSurface_Release(src
);
10285 IDirectDrawSurface_Release(dst
);
10289 destroy_viewport(device
, viewport
);
10290 destroy_material(green
);
10291 IDirectDrawSurface_Release(rt
);
10292 IDirect3DDevice2_Release(device
);
10293 refcount
= IDirectDraw2_Release(ddraw
);
10294 ok(refcount
== 0, "Ddraw object not properly released, refcount %u.\n", refcount
);
10295 DestroyWindow(window
);
10298 static void test_range_colorkey(void)
10300 IDirectDraw2
*ddraw
;
10303 IDirectDrawSurface
*surface
;
10304 DDSURFACEDESC surface_desc
;
10308 window
= create_window();
10309 ddraw
= create_ddraw();
10310 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10311 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10312 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10314 memset(&surface_desc
, 0, sizeof(surface_desc
));
10315 surface_desc
.dwSize
= sizeof(surface_desc
);
10316 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
10317 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10318 surface_desc
.dwWidth
= 1;
10319 surface_desc
.dwHeight
= 1;
10320 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10321 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
10322 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10323 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10324 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10325 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00000000;
10327 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
10328 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10329 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
10330 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10331 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10333 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
10334 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10335 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10336 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10338 /* Same for DDSCAPS_OFFSCREENPLAIN. */
10339 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10340 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10341 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
10342 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10343 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10345 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
10346 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10347 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10348 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10350 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10351 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10352 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10353 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10355 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
10356 ckey
.dwColorSpaceLowValue
= 0x00000000;
10357 ckey
.dwColorSpaceHighValue
= 0x00000001;
10358 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10359 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
10361 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10362 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
10363 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
10364 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
10366 ckey
.dwColorSpaceLowValue
= 0x00000001;
10367 ckey
.dwColorSpaceHighValue
= 0x00000000;
10368 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10369 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
10371 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10372 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
10373 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
10374 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
10376 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
10377 ckey
.dwColorSpaceLowValue
= 0x00000000;
10378 ckey
.dwColorSpaceHighValue
= 0x00000000;
10379 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10380 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
10382 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
10383 ckey
.dwColorSpaceLowValue
= 0x00000001;
10384 ckey
.dwColorSpaceHighValue
= 0x00000000;
10385 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10386 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10387 ckey
.dwColorSpaceLowValue
= 0x00000000;
10388 ckey
.dwColorSpaceHighValue
= 0x00000001;
10389 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10390 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10391 /* Range destination keys don't work either. */
10392 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
10393 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10395 /* Just to show it's not because of A, R, and G having equal values. */
10396 ckey
.dwColorSpaceLowValue
= 0x00000000;
10397 ckey
.dwColorSpaceHighValue
= 0x01010101;
10398 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10399 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10401 /* None of these operations modified the key. */
10402 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10403 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
10404 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
10405 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
10407 IDirectDrawSurface_Release(surface
);
10408 refcount
= IDirectDraw2_Release(ddraw
);
10409 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
10410 DestroyWindow(window
);
10413 static void test_shademode(void)
10415 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10416 IDirect3DMaterial2
*background
;
10417 IDirect3DViewport2
*viewport
;
10418 IDirect3DDevice2
*device
;
10419 IDirectDrawSurface
*rt
;
10420 DWORD color0
, color1
;
10421 IDirectDraw2
*ddraw
;
10427 static D3DLVERTEX quad_strip
[] =
10429 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
10430 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
10431 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
10432 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
10436 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
10437 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
10438 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
10440 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
10441 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
10442 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
10444 static const struct
10448 DWORD color0
, color1
;
10452 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
10453 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
10454 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
10455 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
10456 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
10457 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
10460 window
= create_window();
10461 ddraw
= create_ddraw();
10462 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10463 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10465 skip("Failed to create a 3D device, skipping test.\n");
10466 IDirectDraw2_Release(ddraw
);
10467 DestroyWindow(window
);
10471 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
10472 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10474 background
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
10475 viewport
= create_viewport(device
, 0, 0, 640, 480);
10476 viewport_set_background(device
, viewport
, background
);
10477 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
10478 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
10480 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
10481 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
10483 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
10484 * the color fixups we have to do for FLAT shading will be dependent on that. */
10486 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10488 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10489 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
10491 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
10492 ok(hr
== D3D_OK
, "Failed to set shade mode, hr %#x.\n", hr
);
10494 hr
= IDirect3DDevice2_BeginScene(device
);
10495 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10496 quad
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? quad_strip
: quad_list
;
10497 count
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? 4 : 6;
10498 hr
= IDirect3DDevice2_DrawPrimitive(device
, tests
[i
].primtype
, D3DVT_LVERTEX
, quad
, count
, 0);
10499 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10500 hr
= IDirect3DDevice2_EndScene(device
);
10501 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10503 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
10504 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
10506 /* For D3DSHADE_FLAT it should take the color of the first vertex of
10507 * each triangle. This requires EXT_provoking_vertex or similar
10508 * functionality being available. */
10509 /* PHONG should be the same as GOURAUD, since no hardware implements
10511 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
10512 i
, color0
, tests
[i
].color0
);
10513 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
10514 i
, color1
, tests
[i
].color1
);
10517 destroy_viewport(device
, viewport
);
10518 destroy_material(background
);
10519 IDirectDrawSurface_Release(rt
);
10520 refcount
= IDirect3DDevice2_Release(device
);
10521 ok(!refcount
, "Device has %u references left.\n", refcount
);
10522 IDirectDraw2_Release(ddraw
);
10523 DestroyWindow(window
);
10526 static void test_lockrect_invalid(void)
10529 IDirectDraw2
*ddraw
;
10530 IDirectDrawSurface
*surface1
;
10531 IDirectDrawSurface2
*surface
;
10534 DDSURFACEDESC surface_desc
;
10536 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
10537 static RECT valid
[] =
10542 {120, 60, 128, 68},
10543 {60, 120, 68, 128},
10545 static RECT invalid
[] =
10547 {68, 60, 60, 68}, /* left > right */
10548 {60, 68, 68, 60}, /* top > bottom */
10549 {-8, 60, 0, 68}, /* left < surface */
10550 {60, -8, 68, 0}, /* top < surface */
10551 {-16, 60, -8, 68}, /* right < surface */
10552 {60, -16, 68, -8}, /* bottom < surface */
10553 {60, 60, 136, 68}, /* right > surface */
10554 {60, 60, 68, 136}, /* bottom > surface */
10555 {136, 60, 144, 68}, /* left > surface */
10556 {60, 136, 68, 144}, /* top > surface */
10558 static const struct
10566 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, "sysmem offscreenplain", DDERR_INVALIDPARAMS
},
10567 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, "vidmem offscreenplain", DDERR_INVALIDPARAMS
},
10568 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "sysmem texture", DDERR_INVALIDPARAMS
},
10569 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "vidmem texture", DDERR_INVALIDPARAMS
},
10572 window
= create_window();
10573 ddraw
= create_ddraw();
10574 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10575 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10576 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10578 memset(&hal_caps
, 0, sizeof(hal_caps
));
10579 hal_caps
.dwSize
= sizeof(hal_caps
);
10580 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
10581 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
10582 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
10584 skip("Required surface types not supported, skipping test.\n");
10588 for (r
= 0; r
< ARRAY_SIZE(resources
); ++r
)
10590 memset(&surface_desc
, 0, sizeof(surface_desc
));
10591 surface_desc
.dwSize
= sizeof(surface_desc
);
10592 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10593 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
10594 surface_desc
.dwWidth
= 128;
10595 surface_desc
.dwHeight
= 128;
10596 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10597 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10598 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
10599 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xff0000;
10600 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x00ff00;
10601 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x0000ff;
10603 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
10604 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
10605 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
10606 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface2 interface, hr %#x.\n", hr
);
10607 IDirectDrawSurface_Release(surface1
);
10609 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, NULL
, DDLOCK_WAIT
, NULL
);
10610 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, resources
[r
].name
);
10612 for (i
= 0; i
< ARRAY_SIZE(valid
); ++i
)
10614 RECT
*rect
= &valid
[i
];
10616 memset(&surface_desc
, 0, sizeof(surface_desc
));
10617 surface_desc
.dwSize
= sizeof(surface_desc
);
10619 hr
= IDirectDrawSurface2_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10620 ok(SUCCEEDED(hr
), "Lock failed (%#x) for rect %s, type %s.\n",
10621 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
10623 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
10624 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
10627 for (i
= 0; i
< ARRAY_SIZE(invalid
); ++i
)
10629 RECT
*rect
= &invalid
[i
];
10631 memset(&surface_desc
, 1, sizeof(surface_desc
));
10632 surface_desc
.dwSize
= sizeof(surface_desc
);
10634 hr
= IDirectDrawSurface2_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10635 ok(hr
== resources
[r
].hr
, "Lock returned %#x for rect %s, type %s.\n",
10636 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
10639 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
10640 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
10643 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10646 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10647 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#x, type %s.\n",
10648 hr
, resources
[r
].name
);
10649 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10650 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#x, type %s.\n",
10651 hr
, resources
[r
].name
);
10652 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
10653 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
10655 hr
= IDirectDrawSurface2_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
10656 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#x).\n", wine_dbgstr_rect(&valid
[0]), hr
);
10657 hr
= IDirectDrawSurface2_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
10658 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#x).\n",
10659 wine_dbgstr_rect(&valid
[0]), hr
);
10661 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
10662 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
10664 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
10665 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
10667 IDirectDrawSurface2_Release(surface
);
10671 IDirectDraw2_Release(ddraw
);
10672 DestroyWindow(window
);
10675 static void test_yv12_overlay(void)
10677 IDirectDrawSurface
*src_surface
, *dst_surface
;
10678 RECT rect
= {13, 17, 14, 18};
10679 unsigned int offset
, y
;
10680 unsigned char *base
;
10681 IDirectDraw2
*ddraw
;
10682 DDSURFACEDESC desc
;
10686 window
= create_window();
10687 ddraw
= create_ddraw();
10688 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10689 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10690 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10692 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
10694 skip("Failed to create a YV12 overlay, skipping test.\n");
10698 memset(&desc
, 0, sizeof(desc
));
10699 desc
.dwSize
= sizeof(desc
);
10700 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
10701 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10703 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
10704 "Got unexpected flags %#x.\n", desc
.dwFlags
);
10705 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
10706 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
10707 "Got unexpected caps %#x.\n", desc
.ddsCaps
.dwCaps
);
10708 ok(desc
.dwWidth
== 256, "Got unexpected width %u.\n", desc
.dwWidth
);
10709 ok(desc
.dwHeight
== 256, "Got unexpected height %u.\n", desc
.dwHeight
);
10710 /* The overlay pitch seems to have 256 byte alignment. */
10711 ok(!(U1(desc
).lPitch
& 0xff), "Got unexpected pitch %u.\n", U1(desc
).lPitch
);
10713 /* Fill the surface with some data for the blit test. */
10714 base
= desc
.lpSurface
;
10716 for (y
= 0; y
< desc
.dwHeight
; ++y
)
10718 memset(base
+ U1(desc
).lPitch
* y
, 0x10, desc
.dwWidth
);
10721 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
10723 memset(base
+ U1(desc
).lPitch
* y
, 0x20, desc
.dwWidth
);
10726 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
10728 memset(base
+ U1(desc
).lPitch
* y
, 0x30, desc
.dwWidth
);
10731 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
10732 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10734 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
10735 * other block-based formats like DXT the entire Y channel is stored in
10736 * one big chunk of memory, followed by the chroma channels. So partial
10737 * locks do not really make sense. Show that they are allowed nevertheless
10738 * and the offset points into the luminance data. */
10739 hr
= IDirectDrawSurface_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
10740 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10741 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
10742 ok(offset
== rect
.top
* U1(desc
).lPitch
+ rect
.left
, "Got unexpected offset %u, expected %u.\n",
10743 offset
, rect
.top
* U1(desc
).lPitch
+ rect
.left
);
10744 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
10745 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10747 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
10749 /* Windows XP with a Radeon X1600 GPU refuses to create a second
10750 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
10751 skip("Failed to create a second YV12 surface, skipping blit test.\n");
10752 IDirectDrawSurface_Release(src_surface
);
10756 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
10757 /* VMware rejects YV12 blits. This behavior has not been seen on real
10758 * hardware yet, so mark it broken. */
10759 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#x.\n", hr
);
10763 memset(&desc
, 0, sizeof(desc
));
10764 desc
.dwSize
= sizeof(desc
);
10765 hr
= IDirectDrawSurface_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
10766 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10768 base
= desc
.lpSurface
;
10769 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
10770 base
+= desc
.dwHeight
* U1(desc
).lPitch
;
10771 todo_wine
ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
10772 base
+= desc
.dwHeight
/ 4 * U1(desc
).lPitch
;
10773 todo_wine
ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
10775 hr
= IDirectDrawSurface_Unlock(dst_surface
, NULL
);
10776 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10779 IDirectDrawSurface_Release(dst_surface
);
10780 IDirectDrawSurface_Release(src_surface
);
10782 IDirectDraw2_Release(ddraw
);
10783 DestroyWindow(window
);
10786 static BOOL
dwm_enabled(void)
10790 if (!strcmp(winetest_platform
, "wine"))
10792 if (!pDwmIsCompositionEnabled
)
10794 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
10799 static void test_offscreen_overlay(void)
10801 IDirectDrawSurface
*overlay
, *offscreen
, *primary
;
10802 DDSURFACEDESC surface_desc
;
10803 IDirectDraw2
*ddraw
;
10808 window
= create_window();
10809 ddraw
= create_ddraw();
10810 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10811 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10812 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10814 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
10816 skip("Failed to create a UYVY overlay, skipping test.\n");
10820 memset(&surface_desc
, 0, sizeof(surface_desc
));
10821 surface_desc
.dwSize
= sizeof(surface_desc
);
10822 surface_desc
.dwFlags
= DDSD_CAPS
;
10823 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
10824 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
10825 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
10827 /* On Windows 7, and probably Vista, UpdateOverlay() will return
10828 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
10829 * surface prevents this by disabling the dwm. */
10830 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
10831 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
10832 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
10833 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
10835 /* Try to overlay a NULL surface. */
10836 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
10837 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10838 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
10839 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10841 /* Try to overlay an offscreen surface. */
10842 memset(&surface_desc
, 0, sizeof(surface_desc
));
10843 surface_desc
.dwSize
= sizeof(surface_desc
);
10844 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
10845 surface_desc
.dwWidth
= 64;
10846 surface_desc
.dwHeight
= 64;
10847 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10848 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10849 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10850 surface_desc
.ddpfPixelFormat
.dwFourCC
= 0;
10851 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
10852 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
10853 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
10854 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
10855 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
10856 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
10858 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
10859 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled())
10860 || broken(hr
== E_NOTIMPL
&& ddraw_is_vmware(ddraw
)),
10861 "Failed to update overlay, hr %#x.\n", hr
);
10863 /* Try to overlay the primary with a non-overlay surface. */
10864 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
10865 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
10866 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
10867 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
10869 IDirectDrawSurface_Release(offscreen
);
10870 IDirectDrawSurface_Release(primary
);
10871 IDirectDrawSurface_Release(overlay
);
10873 IDirectDraw2_Release(ddraw
);
10874 DestroyWindow(window
);
10877 static void test_overlay_rect(void)
10879 IDirectDrawSurface
*overlay
, *primary
= NULL
;
10880 DDSURFACEDESC surface_desc
;
10881 RECT rect
= {0, 0, 64, 64};
10882 IDirectDraw2
*ddraw
;
10888 window
= create_window();
10889 ddraw
= create_ddraw();
10890 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10891 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10892 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10894 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
10896 skip("Failed to create a UYVY overlay, skipping test.\n");
10900 memset(&surface_desc
, 0, sizeof(surface_desc
));
10901 surface_desc
.dwSize
= sizeof(surface_desc
);
10902 surface_desc
.dwFlags
= DDSD_CAPS
;
10903 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
10904 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
10905 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
10907 /* On Windows 7, and probably Vista, UpdateOverlay() will return
10908 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
10909 * surface prevents this by disabling the dwm. */
10910 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
10911 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
10912 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
10913 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
10915 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
10918 win_skip("Cannot disable DWM, skipping overlay test.\n");
10922 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
10923 * used. This is not true in Windows Vista and earlier, but changed in
10925 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
10926 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
10927 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
10928 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
10929 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
10930 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10932 /* Show that the overlay position is the (top, left) coordinate of the
10933 * destination rectangle. */
10934 OffsetRect(&rect
, 32, 16);
10935 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
10936 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
10937 pos_x
= -1; pos_y
= -1;
10938 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
10939 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
10940 ok(pos_x
== rect
.left
, "Got unexpected pos_x %d, expected %d.\n", pos_x
, rect
.left
);
10941 ok(pos_y
== rect
.top
, "Got unexpected pos_y %d, expected %d.\n", pos_y
, rect
.top
);
10943 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
10944 * seen that the overlay overlays the whole primary(==screen). */
10945 hr2
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
10946 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#x.\n", hr2
);
10947 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
10948 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
10949 if (SUCCEEDED(hr2
))
10951 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
10952 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
10956 ok(pos_x
== 32, "Got unexpected pos_x %d.\n", pos_x
);
10957 ok(pos_y
== 16, "Got unexpected pos_y %d.\n", pos_y
);
10960 /* The position cannot be retrieved when the overlay is not shown. */
10961 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
10962 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
10963 pos_x
= -1; pos_y
= -1;
10964 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
10965 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#x.\n", hr
);
10966 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
10967 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
10971 IDirectDrawSurface_Release(primary
);
10973 IDirectDrawSurface_Release(overlay
);
10974 IDirectDraw2_Release(ddraw
);
10975 DestroyWindow(window
);
10978 static void test_blt(void)
10980 IDirectDrawSurface
*surface
, *rt
;
10981 DDSURFACEDESC surface_desc
;
10982 IDirect3DDevice2
*device
;
10983 IDirectDraw2
*ddraw
;
10997 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
10998 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
10999 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
11000 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
11001 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
11002 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
11003 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
11004 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
11005 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
11006 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
11009 window
= create_window();
11010 ddraw
= create_ddraw();
11011 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11012 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
11014 skip("Failed to create a 3D device, skipping test.\n");
11015 IDirectDraw2_Release(ddraw
);
11016 DestroyWindow(window
);
11020 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
11021 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
11023 memset(&surface_desc
, 0, sizeof(surface_desc
));
11024 surface_desc
.dwSize
= sizeof(surface_desc
);
11025 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
11026 surface_desc
.dwWidth
= 640;
11027 surface_desc
.dwHeight
= 480;
11028 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11029 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11030 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11032 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
11033 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
11035 hr
= IDirectDrawSurface_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
11036 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
11038 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
11040 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
11041 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11042 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
11044 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
11045 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11046 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
11048 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
11049 NULL
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11050 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11052 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
, NULL
, NULL
, DDBLT_WAIT
, NULL
);
11053 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11056 IDirectDrawSurface_Release(surface
);
11057 IDirectDrawSurface_Release(rt
);
11058 refcount
= IDirect3DDevice2_Release(device
);
11059 ok(!refcount
, "Device has %u references left.\n", refcount
);
11060 IDirectDraw2_Release(ddraw
);
11061 DestroyWindow(window
);
11064 static void test_blt_z_alpha(void)
11066 DWORD blt_flags
[] =
11070 DDBLT_ALPHADESTCONSTOVERRIDE
,
11071 DDBLT_ALPHADESTNEG
,
11072 DDBLT_ALPHADESTSURFACEOVERRIDE
,
11073 DDBLT_ALPHAEDGEBLEND
,
11076 DDBLT_ALPHASRCCONSTOVERRIDE
,
11078 DDBLT_ALPHASRCSURFACEOVERRIDE
,
11081 DDBLT_ZBUFFERDESTCONSTOVERRIDE
,
11082 DDBLT_ZBUFFERDESTOVERRIDE
,
11083 DDBLT_ZBUFFERSRCCONSTOVERRIDE
,
11084 DDBLT_ZBUFFERSRCOVERRIDE
,
11086 IDirectDrawSurface
*src_surface
, *dst_surface
;
11087 DDSURFACEDESC surface_desc
;
11088 IDirectDraw2
*ddraw
;
11097 window
= create_window();
11098 ddraw
= create_ddraw();
11099 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11100 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11101 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11103 memset(&pf
, 0, sizeof(pf
));
11104 pf
.dwSize
= sizeof(pf
);
11105 pf
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
11106 U1(pf
).dwRGBBitCount
= 32;
11107 U2(pf
).dwRBitMask
= 0x00ff0000;
11108 U3(pf
).dwGBitMask
= 0x0000ff00;
11109 U4(pf
).dwBBitMask
= 0x000000ff;
11110 U5(pf
).dwRGBAlphaBitMask
= 0xff000000;
11112 memset(&surface_desc
, 0, sizeof(surface_desc
));
11113 surface_desc
.dwSize
= sizeof(surface_desc
);
11114 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
11115 surface_desc
.dwWidth
= 64;
11116 surface_desc
.dwHeight
= 64;
11117 surface_desc
.ddpfPixelFormat
= pf
;
11118 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11120 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
11121 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
11122 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
11123 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
11125 memset(&fx
, 0, sizeof(fx
));
11126 fx
.dwSize
= sizeof(fx
);
11127 fx
.dwZBufferOpCode
= D3DCMP_NEVER
;
11128 fx
.dwZDestConstBitDepth
= 32;
11129 U1(fx
).dwZDestConst
= 0x11111111;
11130 fx
.dwZSrcConstBitDepth
= 32;
11131 U2(fx
).dwZSrcConst
= 0xeeeeeeee;
11132 fx
.dwAlphaEdgeBlendBitDepth
= 8;
11133 fx
.dwAlphaEdgeBlend
= 0x7f;
11134 fx
.dwAlphaDestConstBitDepth
= 8;
11135 U3(fx
).dwAlphaDestConst
= 0xdd;
11136 fx
.dwAlphaSrcConstBitDepth
= 8;
11137 U4(fx
).dwAlphaSrcConst
= 0x22;
11139 for (i
= 0; i
< ARRAY_SIZE(blt_flags
); ++i
)
11141 U5(fx
).dwFillColor
= 0x3300ff00;
11142 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11143 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11145 U5(fx
).dwFillColor
= 0xccff0000;
11146 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11147 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11149 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, blt_flags
[i
] | DDBLT_WAIT
, &fx
);
11150 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11152 color
= get_surface_color(dst_surface
, 32, 32);
11153 ok(compare_color(color
, 0x0000ff00, 0), "Test %u: Got unexpected color 0x%08x.\n", i
, color
);
11156 IDirectDrawSurface_Release(dst_surface
);
11157 IDirectDrawSurface_Release(src_surface
);
11158 refcount
= IDirectDraw2_Release(ddraw
);
11159 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
11160 DestroyWindow(window
);
11163 static void test_cross_device_blt(void)
11165 IDirectDrawSurface
*surface
, *surface2
, *sysmem_surface
;
11166 IDirect3DDevice2
*device
, *device2
;
11167 IDirectDraw2
*ddraw
, *ddraw2
;
11168 DDSURFACEDESC surface_desc
;
11169 HWND window
, window2
;
11175 window
= create_window();
11176 ddraw
= create_ddraw();
11177 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
11179 skip("Failed to create a 3D device.\n");
11180 IDirectDraw2_Release(ddraw
);
11181 DestroyWindow(window
);
11185 window2
= create_window();
11186 ddraw2
= create_ddraw();
11187 if (!(device2
= create_device(ddraw2
, window2
, DDSCL_NORMAL
)))
11189 skip("Failed to create a 3D device.\n");
11190 IDirectDraw2_Release(ddraw2
);
11191 IDirect3DDevice2_Release(device
);
11192 IDirectDraw2_Release(ddraw
);
11193 DestroyWindow(window
);
11194 DestroyWindow(window2
);
11198 memset(&surface_desc
, 0, sizeof(surface_desc
));
11199 surface_desc
.dwSize
= sizeof(surface_desc
);
11200 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
11201 surface_desc
.dwWidth
= 640;
11202 surface_desc
.dwHeight
= 480;
11203 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
11204 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
11205 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11207 memset(&surface_desc
, 0, sizeof(surface_desc
));
11208 surface_desc
.dwSize
= sizeof(surface_desc
);
11209 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
11210 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_VIDEOMEMORY
;
11211 surface_desc
.dwBackBufferCount
= 2;
11212 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11213 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11215 memset(&surface_desc
, 0, sizeof(surface_desc
));
11216 surface_desc
.dwSize
= sizeof(surface_desc
);
11217 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
11218 surface_desc
.dwWidth
= 640;
11219 surface_desc
.dwHeight
= 480;
11220 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
11221 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
11222 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11223 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
11224 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00007c00;
11225 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x000003e0;
11226 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x0000001f;
11227 hr
= IDirectDraw2_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
11228 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11230 memset(&fx
, 0, sizeof(fx
));
11231 fx
.dwSize
= sizeof(fx
);
11232 U5(fx
).dwFillColor
= 0xff0000ff;
11233 hr
= IDirectDrawSurface_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11234 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
11236 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11237 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
11238 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
11239 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
11240 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11241 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
11242 color
= get_surface_color(surface
, 320, 240);
11243 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
11245 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11246 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
11247 color
= get_surface_color(sysmem_surface
, 320, 240);
11248 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
11250 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11251 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11252 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
11253 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
11255 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11256 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
11257 color
= get_surface_color(sysmem_surface
, 320, 240);
11258 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
11260 IDirectDrawSurface_Release(surface2
);
11261 memset(&surface_desc
, 0, sizeof(surface_desc
));
11262 surface_desc
.dwSize
= sizeof(surface_desc
);
11263 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
11264 surface_desc
.dwWidth
= 640;
11265 surface_desc
.dwHeight
= 480;
11266 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
11267 hr
= IDirectDraw2_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
11268 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11269 hr
= IDirectDrawSurface_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11270 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
11272 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11273 todo_wine
ok(hr
== D3D_OK
, "Failed to blit, hr %#x.\n", hr
);
11274 color
= get_surface_color(sysmem_surface
, 320, 240);
11275 todo_wine
ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11277 IDirectDrawSurface_Release(surface
);
11278 IDirectDrawSurface_Release(surface2
);
11279 IDirectDrawSurface_Release(sysmem_surface
);
11280 refcount
= IDirect3DDevice2_Release(device
);
11281 ok(!refcount
, "Device has %u references left.\n", refcount
);
11282 refcount
= IDirect3DDevice2_Release(device2
);
11283 ok(!refcount
, "Device has %u references left.\n", refcount
);
11284 IDirectDraw2_Release(ddraw
);
11285 IDirectDraw2_Release(ddraw2
);
11286 DestroyWindow(window
);
11287 DestroyWindow(window2
);
11290 static void test_getdc(void)
11292 IDirectDrawSurface
*surface
, *surface2
, *tmp
;
11293 DDSURFACEDESC surface_desc
, map_desc
;
11294 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
11295 IDirectDraw2
*ddraw
;
11296 unsigned int i
, screen_bpp
;
11301 static const struct
11304 DDPIXELFORMAT format
;
11305 BOOL getdc_supported
;
11306 HRESULT alt_result
;
11310 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11311 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
11312 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
11313 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
11314 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11315 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
11316 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11317 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
11318 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
11319 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
11320 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
11321 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11322 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11323 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11324 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11325 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
11326 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11327 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11328 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
11329 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11330 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
11331 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
11332 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
11333 * This is not implemented in wine yet, so disable the test for now.
11334 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
11335 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
11336 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
11338 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
11339 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11340 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
11341 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
11342 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
11343 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11344 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
11345 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11346 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
11347 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11348 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
11349 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11350 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
11351 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11354 window
= create_window();
11355 ddraw
= create_ddraw();
11356 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11357 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11358 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11360 surface_desc
.dwSize
= sizeof(surface_desc
);
11361 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
11362 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
11363 screen_bpp
= U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
;
11365 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
11367 memset(&surface_desc
, 0, sizeof(surface_desc
));
11368 surface_desc
.dwSize
= sizeof(surface_desc
);
11369 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11370 surface_desc
.dwWidth
= 64;
11371 surface_desc
.dwHeight
= 64;
11372 surface_desc
.ddpfPixelFormat
= test_data
[i
].format
;
11373 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11375 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11377 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
11378 if (FAILED(hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11380 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", test_data
[i
].name
, hr
);
11385 dc
= (void *)0x1234;
11386 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11387 if (test_data
[i
].getdc_supported
)
11388 ok(SUCCEEDED(hr
) || broken(hr
== test_data
[i
].alt_result
|| ddraw_is_vmware(ddraw
)),
11389 "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11391 ok(FAILED(hr
), "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11395 unsigned int width_bytes
;
11401 type
= GetObjectType(dc
);
11402 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
11403 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
11404 type
= GetObjectType(bitmap
);
11405 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
11407 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
11408 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
11409 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
11410 dib
.dsBm
.bmType
, test_data
[i
].name
);
11411 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
11412 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
11413 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
11414 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
11415 width_bytes
= ((dib
.dsBm
.bmWidth
* U1(test_data
[i
].format
).dwRGBBitCount
+ 31) >> 3) & ~3;
11416 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
11417 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
11418 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
11419 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
11420 ok(dib
.dsBm
.bmBitsPixel
== U1(test_data
[i
].format
).dwRGBBitCount
,
11421 "Got unexpected bit count %d for format %s.\n",
11422 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
11423 /* Windows XP sets bmBits == NULL for formats that match the screen at least on my r200 GPU. I
11424 * suspect this applies to all HW accelerated pre-WDDM drivers because they can handle gdi access
11425 * to ddraw surfaces themselves instead of going through a sysmem DIB section. */
11426 ok(!!dib
.dsBm
.bmBits
|| broken(!pDwmIsCompositionEnabled
&& dib
.dsBm
.bmBitsPixel
== screen_bpp
),
11427 "Got unexpected bits %p for format %s.\n", dib
.dsBm
.bmBits
, test_data
[i
].name
);
11429 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %u for format %s.\n",
11430 dib
.dsBmih
.biSize
, test_data
[i
].name
);
11431 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
11432 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
11433 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
11434 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
11435 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
11436 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
11437 ok(dib
.dsBmih
.biBitCount
== U1(test_data
[i
].format
).dwRGBBitCount
,
11438 "Got unexpected bit count %u for format %s.\n",
11439 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
11440 ok(dib
.dsBmih
.biCompression
== (U1(test_data
[i
].format
).dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
11441 || broken(U1(test_data
[i
].format
).dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
11442 "Got unexpected compression %#x for format %s.\n",
11443 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
11444 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %u for format %s.\n",
11445 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
11446 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %d for format %s.\n",
11447 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
11448 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %d for format %s.\n",
11449 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
11450 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %u for format %s.\n",
11451 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
11452 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %u for format %s.\n",
11453 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
11455 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
11457 ok((dib
.dsBitfields
[0] == U2(test_data
[i
].format
).dwRBitMask
11458 && dib
.dsBitfields
[1] == U3(test_data
[i
].format
).dwGBitMask
11459 && dib
.dsBitfields
[2] == U4(test_data
[i
].format
).dwBBitMask
)
11460 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
11461 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
11462 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
11466 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
11467 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
11468 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
11470 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
11471 ok(!dib
.dsOffset
, "Got unexpected offset %u for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
11473 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11474 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11478 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
11481 IDirectDrawSurface_Release(surface
);
11486 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
11487 if (FAILED(hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11489 skip("Failed to create mip-mapped texture for format %s (hr %#x), skipping tests.\n",
11490 test_data
[i
].name
, hr
);
11494 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
11495 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11496 hr
= IDirectDrawSurface_GetAttachedSurface(tmp
, &caps
, &surface2
);
11497 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11498 IDirectDrawSurface_Release(tmp
);
11500 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11501 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11502 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11503 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11504 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11505 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11506 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11507 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11509 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11510 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11511 dc2
= (void *)0x1234;
11512 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
11513 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11514 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
11515 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11516 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11517 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11518 ok(hr
== DDERR_NODC
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11520 map_desc
.dwSize
= sizeof(map_desc
);
11521 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11522 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11523 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11524 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11525 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11526 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11527 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11528 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11530 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11531 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11532 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11533 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11534 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11535 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11537 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11538 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11539 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11540 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11541 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11542 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11543 /* Geforce 9600, Windows 7 returns E_FAIL. The unlock still seems to work as intended, after-
11544 * wards the surface can be locked again. ReleaseDC() does not unlock the surface, trying to
11545 * Lock it after ReleaseDC returns DDERR_SURFACEBUSY. ddraw4 and 7 are unaffected. */
11546 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11547 ok(SUCCEEDED(hr
) || broken(ddraw_is_nvidia(ddraw
) && hr
== E_FAIL
),
11548 "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11550 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11551 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11552 hr
= IDirectDrawSurface_GetDC(surface2
, &dc2
);
11553 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11554 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc2
);
11555 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11556 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11557 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11559 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11560 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11561 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
11562 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11563 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc2
);
11564 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11565 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11566 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11568 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11569 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11570 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11571 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11572 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11573 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11574 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11575 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11577 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11578 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11579 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11580 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11581 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11582 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11583 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11584 ok(SUCCEEDED(hr
) || broken(ddraw_is_nvidia(ddraw
) && hr
== E_FAIL
),
11585 "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11587 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11588 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11589 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11590 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11591 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11592 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11593 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11594 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11596 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11597 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11598 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11599 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11600 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11601 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11602 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11603 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11605 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11606 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11607 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11608 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11609 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11610 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11611 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11612 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11614 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11615 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11616 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11617 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11618 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11619 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11620 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11621 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11622 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11623 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11625 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11626 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11627 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11628 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11629 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11630 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11631 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11632 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11633 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11634 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11636 IDirectDrawSurface_Release(surface2
);
11637 IDirectDrawSurface_Release(surface
);
11640 IDirectDraw2_Release(ddraw
);
11641 DestroyWindow(window
);
11644 static void test_draw_primitive(void)
11646 static WORD indices
[] = {0, 1, 2, 3};
11647 static D3DVERTEX quad
[] =
11649 {{-1.0f
}, {-1.0f
}, {0.0f
}},
11650 {{-1.0f
}, { 1.0f
}, {0.0f
}},
11651 {{ 1.0f
}, {-1.0f
}, {0.0f
}},
11652 {{ 1.0f
}, { 1.0f
}, {0.0f
}},
11654 IDirect3DViewport2
*viewport
;
11655 IDirect3DDevice2
*device
;
11656 IDirectDraw2
*ddraw
;
11662 window
= create_window();
11663 ddraw
= create_ddraw();
11664 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11665 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
11667 skip("Failed to create a 3D device, skipping test.\n");
11668 IDirectDraw2_Release(ddraw
);
11669 DestroyWindow(window
);
11673 viewport
= create_viewport(device
, 0, 0, 640, 480);
11674 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
11675 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
11677 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
11678 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
11680 IDirect3D2_Release(d3d
);
11682 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, NULL
, 0, 0);
11683 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11684 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, 0);
11685 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11687 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, indices
, 4, 0);
11688 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11690 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, NULL
, 0, 0);
11691 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11692 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
11693 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11694 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, indices
, 4, 0);
11695 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11697 destroy_viewport(device
, viewport
);
11698 refcount
= IDirect3DDevice2_Release(device
);
11699 ok(!refcount
, "Device has %u references left.\n", refcount
);
11700 IDirectDraw2_Release(ddraw
);
11701 DestroyWindow(window
);
11704 static void test_edge_antialiasing_blending(void)
11706 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
11707 IDirect3DMaterial2
*green_background
;
11708 IDirect3DMaterial2
*red_background
;
11709 IDirectDrawSurface
*offscreen
, *ds
;
11710 D3DDEVICEDESC hal_desc
, hel_desc
;
11711 IDirect3DViewport2
*viewport
;
11712 DDSURFACEDESC surface_desc
;
11713 IDirect3DDevice2
*device
;
11714 IDirectDraw2
*ddraw
;
11720 static D3DMATRIX mat
=
11722 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11723 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11724 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11725 0.0f
, 0.0f
, 0.0f
, 1.0f
,
11727 static D3DLVERTEX green_quad
[] =
11729 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
11730 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
11731 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
11732 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
11734 static D3DLVERTEX red_quad
[] =
11736 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xccff0000}},
11737 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xccff0000}},
11738 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xccff0000}},
11739 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xccff0000}},
11742 window
= create_window();
11743 ddraw
= create_ddraw();
11744 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11745 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
11747 skip("Failed to create a 3D device.\n");
11748 DestroyWindow(window
);
11752 memset(&hal_desc
, 0, sizeof(hal_desc
));
11753 hal_desc
.dwSize
= sizeof(hal_desc
);
11754 memset(&hel_desc
, 0, sizeof(hel_desc
));
11755 hel_desc
.dwSize
= sizeof(hel_desc
);
11756 hr
= IDirect3DDevice2_GetCaps(device
, &hal_desc
, &hel_desc
);
11757 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
11758 trace("HAL line edge antialiasing support: %#x.\n",
11759 hal_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
11760 trace("HAL triangle edge antialiasing support: %#x.\n",
11761 hal_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
11762 trace("HEL line edge antialiasing support: %#x.\n",
11763 hel_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
11764 trace("HEL triangle edge antialiasing support: %#x.\n",
11765 hel_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
11767 memset(&surface_desc
, 0, sizeof(surface_desc
));
11768 surface_desc
.dwSize
= sizeof(surface_desc
);
11769 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
11770 surface_desc
.dwWidth
= 640;
11771 surface_desc
.dwHeight
= 480;
11772 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
11773 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
11774 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
11775 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
11776 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
11777 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
11778 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
11779 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
11780 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
11781 ok(hr
== D3D_OK
, "Creating the offscreen render target failed, hr %#x.\n", hr
);
11783 ds
= get_depth_stencil(device
);
11784 hr
= IDirectDrawSurface_AddAttachedSurface(offscreen
, ds
);
11785 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
11786 IDirectDrawSurface_Release(ds
);
11788 hr
= IDirect3DDevice2_SetRenderTarget(device
, offscreen
, 0);
11789 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
11791 red_background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 0.8f
);
11792 green_background
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.5f
);
11794 viewport
= create_viewport(device
, 0, 0, 640, 480);
11795 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
11796 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
11798 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
11799 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
11800 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
11801 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
11802 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
11803 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
11804 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
11805 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
11806 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
11807 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
11808 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
11809 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
11811 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
11812 ok(SUCCEEDED(hr
), "Failed to enable blending, hr %#x.\n", hr
);
11813 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
11814 ok(SUCCEEDED(hr
), "Failed to set src blend, hr %#x.\n", hr
);
11815 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
11816 ok(SUCCEEDED(hr
), "Failed to set dest blend, hr %#x.\n", hr
);
11818 viewport_set_background(device
, viewport
, red_background
);
11819 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11820 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
11821 hr
= IDirect3DDevice2_BeginScene(device
);
11822 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11823 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
11824 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11825 hr
= IDirect3DDevice2_EndScene(device
);
11826 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11827 color
= get_surface_color(offscreen
, 320, 240);
11828 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
11830 viewport_set_background(device
, viewport
, green_background
);
11831 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11832 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
11833 hr
= IDirect3DDevice2_BeginScene(device
);
11834 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11835 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
11836 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11837 hr
= IDirect3DDevice2_EndScene(device
);
11838 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11839 color
= get_surface_color(offscreen
, 320, 240);
11840 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
11842 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
11843 ok(SUCCEEDED(hr
), "Failed to disable blending, hr %#x.\n", hr
);
11845 viewport_set_background(device
, viewport
, red_background
);
11846 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11847 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
11848 hr
= IDirect3DDevice2_BeginScene(device
);
11849 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11850 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
11851 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11852 hr
= IDirect3DDevice2_EndScene(device
);
11853 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11854 color
= get_surface_color(offscreen
, 320, 240);
11855 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
11857 viewport_set_background(device
, viewport
, green_background
);
11858 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11859 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
11860 hr
= IDirect3DDevice2_BeginScene(device
);
11861 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11862 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
11863 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11864 hr
= IDirect3DDevice2_EndScene(device
);
11865 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11866 color
= get_surface_color(offscreen
, 320, 240);
11867 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
11869 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_EDGEANTIALIAS
, TRUE
);
11870 ok(SUCCEEDED(hr
), "Failed to enable edge antialiasing, hr %#x.\n", hr
);
11872 viewport_set_background(device
, viewport
, red_background
);
11873 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11874 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
11875 hr
= IDirect3DDevice2_BeginScene(device
);
11876 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11877 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
11878 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11879 hr
= IDirect3DDevice2_EndScene(device
);
11880 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11881 color
= get_surface_color(offscreen
, 320, 240);
11882 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
11884 viewport_set_background(device
, viewport
, green_background
);
11885 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11886 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
11887 hr
= IDirect3DDevice2_BeginScene(device
);
11888 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11889 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
11890 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11891 hr
= IDirect3DDevice2_EndScene(device
);
11892 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11893 color
= get_surface_color(offscreen
, 320, 240);
11894 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
11896 IDirectDrawSurface_Release(offscreen
);
11897 destroy_viewport(device
, viewport
);
11898 destroy_material(red_background
);
11899 destroy_material(green_background
);
11900 refcount
= IDirect3DDevice2_Release(device
);
11901 ok(!refcount
, "Device has %u references left.\n", refcount
);
11902 IDirectDraw2_Release(ddraw
);
11903 DestroyWindow(window
);
11906 /* TransformVertices always writes 32 bytes regardless of the input / output stride.
11907 * The stride is honored for navigating to the next vertex. 3 floats input position
11908 * are read, and 16 bytes extra vertex data are copied around. */
11909 struct transform_input
11911 float x
, y
, z
, unused1
; /* Position data, transformed. */
11912 DWORD v1
, v2
, v3
, v4
; /* Extra data, e.g. color and texture coords, copied. */
11916 struct transform_output
11919 DWORD v1
, v2
, v3
, v4
;
11920 DWORD unused3
, unused4
;
11923 static void test_transform_vertices(void)
11925 IDirect3DDevice2
*device
;
11926 IDirectDrawSurface
*rt
;
11927 IDirectDraw2
*ddraw
;
11932 IDirect3DViewport2
*viewport
;
11933 IDirect3DMaterial2
*background
;
11935 static struct transform_input position_tests
[] =
11937 { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
11938 { 1.0f
, 1.0f
, 1.0f
, 8.0f
, 6, 7, 8, 9, 10},
11939 {-1.0f
, -1.0f
, -1.0f
, 4.0f
, 11, 12, 13, 14, 15},
11940 { 0.5f
, 0.5f
, 0.5f
, 2.0f
, 16, 17, 18, 19, 20},
11941 {-0.5f
, -0.5f
, -0.5f
, 1.0f
, ~1U, ~2U, ~3U, ~4U, ~5U},
11942 {-0.5f
, -0.5f
, 0.0f
, 0.0f
, ~6U, ~7U, ~8U, ~9U, ~0U},
11944 static struct transform_input cliptest
[] =
11946 { 25.59f
, 25.59f
, 1.0f
, 0.0f
, 1, 2, 3, 4, 5},
11947 { 25.61f
, 25.61f
, 1.01f
, 0.0f
, 1, 2, 3, 4, 5},
11948 {-25.59f
, -25.59f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
11949 {-25.61f
, -25.61f
, -0.01f
, 0.0f
, 1, 2, 3, 4, 5},
11951 static struct transform_input offscreentest
[] =
11953 {128.1f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
11955 struct transform_output out
[ARRAY_SIZE(position_tests
)];
11956 D3DHVERTEX out_h
[ARRAY_SIZE(position_tests
)];
11957 D3DTRANSFORMDATA transformdata
;
11958 static const D3DVIEWPORT vp_template
=
11960 sizeof(vp_template
), 0, 0, 256, 256, 5.0f
, 5.0f
, 256.0f
, 256.0f
, -25.0f
, 60.0f
11962 D3DVIEWPORT vp_data
=
11964 sizeof(vp_data
), 0, 0, 256, 256, 1.0f
, 1.0f
, 256.0f
, 256.0f
, 0.0f
, 1.0f
11966 D3DVIEWPORT2 vp2_data
;
11969 static D3DMATRIX mat_scale
=
11971 2.0f
, 0.0f
, 0.0f
, 0.0f
,
11972 0.0f
, 2.0f
, 0.0f
, 0.0f
,
11973 0.0f
, 0.0f
, 2.0f
, 0.0f
,
11974 0.0f
, 0.0f
, 0.0f
, 1.0f
,
11978 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11979 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11980 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11981 1.0f
, 0.0f
, 0.0f
, 1.0f
,
11985 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11986 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11987 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11988 0.0f
, 1.0f
, 0.0f
, 1.0f
,
11992 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11993 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11994 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11995 0.0f
, 19.2f
, 0.0f
, 2.0f
,
11999 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12000 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12001 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12002 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12004 static D3DLVERTEX quad
[] =
12006 {{-0.75f
},{-0.5f
}, {0.0f
}, 0, {0xffff0000}},
12007 {{-0.75f
},{ 0.25f
}, {0.0f
}, 0, {0xffff0000}},
12008 {{ 0.5f
}, {-0.5f
}, {0.0f
}, 0, {0xffff0000}},
12009 {{ 0.5f
}, { 0.25f
}, {0.0f
}, 0, {0xffff0000}},
12011 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12014 for (i
= 0; i
< ARRAY_SIZE(out
); ++i
)
12016 out
[i
].unused3
= 0xdeadbeef;
12017 out
[i
].unused4
= 0xcafecafe;
12020 window
= create_window();
12021 ddraw
= create_ddraw();
12022 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12023 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
12025 skip("Failed to create a 3D device, skipping test.\n");
12026 IDirectDraw2_Release(ddraw
);
12027 DestroyWindow(window
);
12030 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
12031 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
12033 viewport
= create_viewport(device
, 0, 0, 256, 256);
12034 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12035 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12037 memset(&transformdata
, 0, sizeof(transformdata
));
12038 transformdata
.dwSize
= sizeof(transformdata
);
12039 transformdata
.lpIn
= position_tests
;
12040 transformdata
.dwInSize
= sizeof(position_tests
[0]);
12041 transformdata
.lpOut
= out
;
12042 transformdata
.dwOutSize
= sizeof(out
[0]);
12043 transformdata
.lpHOut
= NULL
;
12045 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12046 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12047 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12048 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12050 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12052 static const struct vec4 cmp
[] =
12054 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {129.0f
, 127.0f
, 1.0f
, 1.0f
}, {127.0f
, 129.0f
, -1.0f
, 1.0f
},
12055 {128.5f
, 127.5f
, 0.5f
, 1.0f
}, {127.5f
, 128.5f
, -0.5f
, 1.0f
}, {127.5f
, 128.5f
, 0.0f
, 1.0f
}
12058 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12059 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12060 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12061 ok(out
[i
].v1
== position_tests
[i
].v1
&& out
[i
].v2
== position_tests
[i
].v2
12062 && out
[i
].v3
== position_tests
[i
].v3
&& out
[i
].v4
== position_tests
[i
].v4
,
12063 "Vertex %u payload is %u %u %u %u.\n", i
, out
[i
].v1
, out
[i
].v2
, out
[i
].v3
, out
[i
].v4
);
12064 ok(out
[i
].unused3
== 0xdeadbeef && out
[i
].unused4
== 0xcafecafe,
12065 "Vertex %u unused data is %#x, %#x.\n", i
, out
[i
].unused3
, out
[i
].unused4
);
12068 vp_data
= vp_template
;
12069 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12070 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12071 offscreen
= 0xdeadbeef;
12072 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12073 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12074 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12075 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12077 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12079 static const struct vec4 cmp
[] =
12081 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {133.0f
, 123.0f
, 1.0f
, 1.0f
}, {123.0f
, 133.0f
, -1.0f
, 1.0f
},
12082 {130.5f
, 125.5f
, 0.5f
, 1.0f
}, {125.5f
, 130.5f
, -0.5f
, 1.0f
}, {125.5f
, 130.5f
, 0.0f
, 1.0f
}
12084 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12085 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12086 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12091 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12092 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12093 offscreen
= 0xdeadbeef;
12094 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12095 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12096 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12097 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12098 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12100 static const struct vec4 cmp
[] =
12102 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, {133.0f
, 153.0f
, -1.0f
, 1.0f
},
12103 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, {135.5f
, 150.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
12105 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12106 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12107 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12110 transformdata
.lpHOut
= out_h
;
12111 offscreen
= 0xdeadbeef;
12112 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12113 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12114 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12115 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12116 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12118 static const D3DHVERTEX cmp_h
[] =
12120 {0, { 0.0f
}, { 0.0f
}, { 0.0f
}}, {0, { 1.0f
}, { 1.0f
}, {1.0f
}},
12121 {D3DCLIP_FRONT
, {-1.0f
}, {-1.0f
}, {-1.0f
}}, {0, { 0.5f
}, { 0.5f
}, {0.5f
}},
12122 {D3DCLIP_FRONT
, {-0.5f
}, {-0.5f
}, {-0.5f
}}, {0, {-0.5f
}, {-0.5f
}, {0.0f
}}
12124 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
12125 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
12126 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
12127 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
12128 "HVertex %u differs. Got %#x %f %f %f.\n", i
,
12129 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
12131 /* No scheme has been found behind those return values. It seems to be
12132 * whatever data windows has when throwing the vertex away. Modify the
12133 * input test vertices to test this more. Depending on the input data
12134 * it can happen that the z coord gets written into y, or similar things. */
12137 static const struct vec4 cmp
[] =
12139 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, { -1.0f
, -1.0f
, 0.5f
, 1.0f
},
12140 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, { -0.5f
, -0.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
12142 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12143 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12144 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12148 transformdata
.lpIn
= cliptest
;
12149 transformdata
.dwInSize
= sizeof(cliptest
[0]);
12150 offscreen
= 0xdeadbeef;
12151 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12152 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12153 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12154 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12155 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12157 static const DWORD flags
[] =
12160 D3DCLIP_RIGHT
| D3DCLIP_BACK
| D3DCLIP_TOP
,
12162 D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,
12164 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
12167 vp_data
= vp_template
;
12168 vp_data
.dwWidth
= 10;
12169 vp_data
.dwHeight
= 480;
12170 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12171 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12172 offscreen
= 0xdeadbeef;
12173 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12174 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12175 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12176 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12177 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12179 static const DWORD flags
[] =
12182 D3DCLIP_RIGHT
| D3DCLIP_BACK
,
12184 D3DCLIP_LEFT
| D3DCLIP_FRONT
,
12186 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
12189 vp_data
= vp_template
;
12190 vp_data
.dwWidth
= 256;
12191 vp_data
.dwHeight
= 256;
12192 vp_data
.dvScaleX
= 1;
12193 vp_data
.dvScaleY
= 1;
12194 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12195 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12196 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12197 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12198 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12199 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12200 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12202 static const DWORD flags
[] =
12209 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
12212 /* Finally try to figure out how the DWORD dwOffscreen works.
12213 * It is a logical AND of the vertices' dwFlags members. */
12214 vp_data
= vp_template
;
12215 vp_data
.dwWidth
= 5;
12216 vp_data
.dwHeight
= 5;
12217 vp_data
.dvScaleX
= 10000.0f
;
12218 vp_data
.dvScaleY
= 10000.0f
;
12219 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12220 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12221 transformdata
.lpIn
= cliptest
;
12222 offscreen
= 0xdeadbeef;
12223 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12224 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12225 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12226 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12228 offscreen
= 0xdeadbeef;
12229 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12230 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12231 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12232 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
12233 offscreen
= 0xdeadbeef;
12234 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
12235 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12236 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12237 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
12238 hr
= IDirect3DViewport2_TransformVertices(viewport
, 3,
12239 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12240 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12241 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12243 transformdata
.lpIn
= cliptest
+ 1;
12244 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12245 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12246 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12247 ok(offscreen
== (D3DCLIP_BACK
| D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
12249 transformdata
.lpIn
= cliptest
+ 2;
12250 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12251 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12252 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12253 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
12254 offscreen
= 0xdeadbeef;
12255 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
12256 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12257 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12258 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
12260 transformdata
.lpIn
= cliptest
+ 3;
12261 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12262 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12263 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12264 ok(offscreen
== (D3DCLIP_FRONT
| D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
12266 transformdata
.lpIn
= offscreentest
;
12267 transformdata
.dwInSize
= sizeof(offscreentest
[0]);
12268 vp_data
= vp_template
;
12269 vp_data
.dwWidth
= 257;
12270 vp_data
.dwHeight
= 257;
12271 vp_data
.dvScaleX
= 1.0f
;
12272 vp_data
.dvScaleY
= 1.0f
;
12273 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12274 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12275 offscreen
= 0xdeadbeef;
12276 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12277 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12278 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12279 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12281 vp_data
.dwWidth
= 256;
12282 vp_data
.dwHeight
= 256;
12283 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12284 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12285 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12286 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12287 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12288 ok(offscreen
== D3DCLIP_RIGHT
, "Offscreen is %x.\n", offscreen
);
12290 /* Test the effect of Matrices.
12292 * Basically the x coordinate ends up as ((x + 1) * 2 + 0) * 5 and
12293 * y as ((y + 0) * 2 + 1) * 5. The 5 comes from dvScaleX/Y, 2 from
12294 * the view matrix and the +1's from the world and projection matrix. */
12297 vp_data
.dwWidth
= 256;
12298 vp_data
.dwHeight
= 256;
12299 vp_data
.dvScaleX
= 5.0f
;
12300 vp_data
.dvScaleY
= 5.0f
;
12301 vp_data
.dvMinZ
= 0.0f
;
12302 vp_data
.dvMaxZ
= 1.0f
;
12303 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12304 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12306 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_translate1
);
12307 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12308 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_scale
);
12309 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12310 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_translate2
);
12311 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12313 transformdata
.lpIn
= position_tests
;
12314 transformdata
.dwInSize
= sizeof(position_tests
[0]);
12315 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12316 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12317 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12319 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12321 static const struct vec4 cmp
[] =
12323 {138.0f
, 123.0f
, 0.0f
, 1.0f
}, {148.0f
, 113.0f
, 2.0f
, 1.0f
}, {128.0f
, 133.0f
, -2.0f
, 1.0f
},
12324 {143.0f
, 118.0f
, 1.0f
, 1.0f
}, {133.0f
, 128.0f
, -1.0f
, 1.0f
}, {133.0f
, 128.0f
, 0.0f
, 1.0f
}
12327 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12328 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12329 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12332 /* Invalid flags. */
12333 offscreen
= 0xdeadbeef;
12334 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12335 &transformdata
, 0, &offscreen
);
12336 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12337 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12339 /* NULL transform data. */
12340 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12341 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12342 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12343 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12344 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12345 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12346 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12347 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12349 /* NULL transform data and NULL dwOffscreen.
12351 * Valid transform data + NULL dwOffscreen -> crash. */
12352 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12353 NULL
, D3DTRANSFORM_UNCLIPPED
, NULL
);
12354 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12357 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12358 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12359 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12360 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12361 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12362 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12363 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12364 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
12366 /* Invalid sizes. */
12367 offscreen
= 0xdeadbeef;
12368 transformdata
.dwSize
= sizeof(transformdata
) - 1;
12369 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12370 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12371 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12372 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12373 transformdata
.dwSize
= sizeof(transformdata
) + 1;
12374 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12375 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12376 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12377 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12379 /* NULL lpIn or lpOut -> crash, except when transforming 0 vertices. */
12380 transformdata
.dwSize
= sizeof(transformdata
);
12381 transformdata
.lpIn
= NULL
;
12382 transformdata
.lpOut
= NULL
;
12383 offscreen
= 0xdeadbeef;
12384 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12385 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12386 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12387 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
12389 /* Test how vertices are transformed during draws. */
12392 vp_data
.dwWidth
= 200;
12393 vp_data
.dwHeight
= 400;
12394 vp_data
.dvScaleX
= 20.0f
;
12395 vp_data
.dvScaleY
= 50.0f
;
12396 vp_data
.dvMinZ
= 0.0f
;
12397 vp_data
.dvMaxZ
= 1.0f
;
12398 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12399 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12400 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
12401 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
12403 ok(SUCCEEDED(hr
), "Failed to clear the render target, hr %#x.\n", hr
);
12404 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 0.0f
);
12405 viewport_set_background(device
, viewport
, background
);
12406 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12407 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12409 hr
= IDirect3DDevice2_BeginScene(device
);
12410 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12411 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
12412 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12413 hr
= IDirect3DDevice2_EndScene(device
);
12414 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12416 color
= get_surface_color(rt
, 128, 143);
12417 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12418 color
= get_surface_color(rt
, 132, 143);
12419 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12420 color
= get_surface_color(rt
, 128, 147);
12421 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12422 color
= get_surface_color(rt
, 132, 147);
12423 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12425 color
= get_surface_color(rt
, 177, 217);
12426 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12427 color
= get_surface_color(rt
, 181, 217);
12428 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12429 color
= get_surface_color(rt
, 177, 221);
12430 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12431 color
= get_surface_color(rt
, 181, 221);
12432 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12434 /* Test D3DVIEWPORT2 behavior. */
12435 vp2_data
.dwSize
= sizeof(vp2_data
);
12438 vp2_data
.dwWidth
= 200;
12439 vp2_data
.dwHeight
= 400;
12440 vp2_data
.dvClipX
= -0.5f
;
12441 vp2_data
.dvClipY
= 4.0f
;
12442 vp2_data
.dvClipWidth
= 5.0f
;
12443 vp2_data
.dvClipHeight
= 10.0f
;
12444 vp2_data
.dvMinZ
= 0.0f
;
12445 vp2_data
.dvMaxZ
= 2.0f
;
12446 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp2_data
);
12447 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
12448 transformdata
.lpIn
= position_tests
;
12449 transformdata
.lpOut
= out
;
12450 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12451 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12452 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12453 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12455 static const struct vec4 cmp
[] =
12457 {120.0f
, 140.0f
, 0.0f
, 1.0f
}, {200.0f
, 60.0f
, 1.0f
, 1.0f
}, {40.0f
, 220.0f
, -1.0f
, 1.0f
},
12458 {160.0f
, 100.0f
, 0.5f
, 1.0f
}, { 80.0f
, 180.0f
, -0.5f
, 1.0f
}, {80.0f
, 180.0f
, 0.0f
, 1.0f
}
12461 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12462 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12463 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12466 memset(&mat
, 0, sizeof(mat
));
12467 mat
.dwSize
= sizeof(mat
);
12468 U1(U(mat
).diffuse
).r
= 0.0f
;
12469 U2(U(mat
).diffuse
).g
= 1.0f
;
12470 U3(U(mat
).diffuse
).b
= 0.0f
;
12471 U4(U(mat
).diffuse
).a
= 0.0f
;
12472 hr
= IDirect3DMaterial2_SetMaterial(background
, &mat
);
12473 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
12474 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12475 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12477 hr
= IDirect3DDevice2_BeginScene(device
);
12478 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12479 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
12480 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12481 hr
= IDirect3DDevice2_EndScene(device
);
12482 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12484 color
= get_surface_color(rt
, 58, 118);
12485 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12486 color
= get_surface_color(rt
, 62, 118);
12487 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12488 color
= get_surface_color(rt
, 58, 122);
12489 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12490 color
= get_surface_color(rt
, 62, 122);
12491 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12493 color
= get_surface_color(rt
, 157, 177);
12494 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12495 color
= get_surface_color(rt
, 161, 177);
12496 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12497 color
= get_surface_color(rt
, 157, 181);
12498 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12499 color
= get_surface_color(rt
, 161, 181);
12500 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12502 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_identity
);
12503 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12504 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_identity
);
12505 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12506 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_transform3
);
12507 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12509 vp2_data
.dwX
= 0.0;
12510 vp2_data
.dwY
= 0.0;
12511 vp2_data
.dwWidth
= 1;
12512 vp2_data
.dwHeight
= 1;
12513 vp2_data
.dvClipX
= -12.8f
;
12514 vp2_data
.dvClipY
= 12.8f
+ mat_transform3
._42
/ mat_transform3
._44
;
12515 vp2_data
.dvClipWidth
= 25.6f
;
12516 vp2_data
.dvClipHeight
= 25.6f
;
12517 vp2_data
.dvMinZ
= 0.0f
;
12518 vp2_data
.dvMaxZ
= 0.5f
;
12519 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp2_data
);
12520 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
12521 transformdata
.lpIn
= cliptest
;
12522 transformdata
.dwInSize
= sizeof(cliptest
[0]);
12523 offscreen
= 0xdeadbeef;
12524 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12525 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12526 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12527 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12528 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12530 static const D3DHVERTEX cmp_h
[] =
12532 {0, { 25.59f
}, { 44.79f
}, { 1.0f
}},
12533 {D3DCLIP_RIGHT
| D3DCLIP_TOP
| D3DCLIP_BACK
, { 25.61f
}, { 44.81f
}, { 1.01f
}},
12534 {0, {-25.59f
}, {-6.39f
}, { 0.0f
}},
12535 {D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,{-25.61f
}, {-6.41f
}, {-0.01f
}},
12537 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
12538 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
12539 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
12540 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
12541 "HVertex %u differs. Got %#x %f %f %f.\n", i
,
12542 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
12545 IDirectDrawSurface_Release(rt
);
12546 destroy_viewport(device
, viewport
);
12547 IDirect3DMaterial2_Release(background
);
12548 refcount
= IDirect3DDevice_Release(device
);
12549 ok(!refcount
, "Device has %u references left.\n", refcount
);
12550 IDirectDraw2_Release(ddraw
);
12551 DestroyWindow(window
);
12554 static void test_display_mode_surface_pixel_format(void)
12556 unsigned int width
, height
, bpp
;
12557 IDirectDrawSurface
*surface
;
12558 DDSURFACEDESC surface_desc
;
12559 IDirectDraw2
*ddraw
;
12564 if (!(ddraw
= create_ddraw()))
12566 skip("Failed to create ddraw.\n");
12570 surface_desc
.dwSize
= sizeof(surface_desc
);
12571 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
12572 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
12573 width
= surface_desc
.dwWidth
;
12574 height
= surface_desc
.dwHeight
;
12576 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
12577 0, 0, width
, height
, NULL
, NULL
, NULL
, NULL
);
12578 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
12579 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12582 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 16, 0, 0)))
12584 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0)))
12586 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
12588 ok(bpp
, "Set display mode failed.\n");
12590 surface_desc
.dwSize
= sizeof(surface_desc
);
12591 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
12592 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
12593 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
12594 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
12595 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
12596 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
12598 memset(&surface_desc
, 0, sizeof(surface_desc
));
12599 surface_desc
.dwSize
= sizeof(surface_desc
);
12600 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
12601 surface_desc
.dwBackBufferCount
= 1;
12602 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_PRIMARYSURFACE
;
12603 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12604 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
12605 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
12606 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
12607 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
12608 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
12609 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
12610 surface_desc
.ddpfPixelFormat
.dwFlags
);
12611 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
12612 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
12613 IDirectDrawSurface_Release(surface
);
12615 memset(&surface_desc
, 0, sizeof(surface_desc
));
12616 surface_desc
.dwSize
= sizeof(surface_desc
);
12617 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
12618 surface_desc
.dwWidth
= width
;
12619 surface_desc
.dwHeight
= height
;
12620 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12621 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12622 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
12623 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
12624 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
12625 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
12626 surface_desc
.ddpfPixelFormat
.dwFlags
);
12627 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
12628 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
12629 IDirectDrawSurface_Release(surface
);
12631 refcount
= IDirectDraw2_Release(ddraw
);
12632 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
12633 DestroyWindow(window
);
12636 static void test_surface_desc_size(void)
12641 DDSURFACEDESC desc1
;
12642 DDSURFACEDESC2 desc2
;
12645 IDirectDrawSurface7
*surface7
;
12646 IDirectDrawSurface2
*surface2
;
12647 IDirectDrawSurface
*surface
;
12648 DDSURFACEDESC surface_desc
;
12649 HRESULT expected_hr
, hr
;
12650 IDirectDraw2
*ddraw
;
12654 static const struct
12661 {DDSCAPS_OFFSCREENPLAIN
, "offscreenplain"},
12662 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "systemmemory texture"},
12663 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "videomemory texture"},
12665 static const unsigned int desc_sizes
[] =
12667 sizeof(DDSURFACEDESC
),
12668 sizeof(DDSURFACEDESC2
),
12669 sizeof(DDSURFACEDESC
) + 1,
12670 sizeof(DDSURFACEDESC2
) + 1,
12671 2 * sizeof(DDSURFACEDESC
),
12672 2 * sizeof(DDSURFACEDESC2
),
12673 sizeof(DDSURFACEDESC
) - 1,
12674 sizeof(DDSURFACEDESC2
) - 1,
12675 sizeof(DDSURFACEDESC
) / 2,
12676 sizeof(DDSURFACEDESC2
) / 2,
12681 sizeof(desc
) - 100,
12684 if (!(ddraw
= create_ddraw()))
12686 skip("Failed to create ddraw.\n");
12689 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
12690 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12692 for (i
= 0; i
< ARRAY_SIZE(surface_caps
); ++i
)
12694 memset(&surface_desc
, 0, sizeof(surface_desc
));
12695 surface_desc
.dwSize
= sizeof(surface_desc
);
12696 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
12697 surface_desc
.ddsCaps
.dwCaps
= surface_caps
[i
].caps
;
12698 surface_desc
.dwHeight
= 128;
12699 surface_desc
.dwWidth
= 128;
12700 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
12702 skip("Failed to create surface, type %s.\n", surface_caps
[i
].name
);
12705 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface2
, (void **)&surface2
);
12706 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface2, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
12707 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface7
, (void **)&surface7
);
12708 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface7, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
12710 /* GetSurfaceDesc() */
12711 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
12713 memset(&desc
, 0, sizeof(desc
));
12714 desc
.dwSize
= desc_sizes
[j
];
12715 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
12716 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
.desc1
);
12717 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
12718 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
12720 memset(&desc
, 0, sizeof(desc
));
12721 desc
.dwSize
= desc_sizes
[j
];
12722 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
12723 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface2
, &desc
.desc1
);
12724 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
12725 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
12727 memset(&desc
, 0, sizeof(desc
));
12728 desc
.dwSize
= desc_sizes
[j
];
12729 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC2
) ? DD_OK
: DDERR_INVALIDPARAMS
;
12730 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface7
, &desc
.desc2
);
12731 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
12732 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
12736 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
12738 const BOOL valid_size
= desc_sizes
[j
] == sizeof(DDSURFACEDESC
)
12739 || desc_sizes
[j
] == sizeof(DDSURFACEDESC2
);
12740 DWORD expected_texture_stage
;
12742 memset(&desc
, 0, sizeof(desc
));
12743 desc
.dwSize
= desc_sizes
[j
];
12744 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
12745 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
12746 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
.desc1
, 0, 0);
12747 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
12748 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
12749 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
12750 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
12751 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
12752 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
12753 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
12756 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
12757 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
12758 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
12759 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
12760 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
12761 todo_wine_if(!expected_texture_stage
)
12762 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
12763 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
12764 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
12765 IDirectDrawSurface_Unlock(surface
, NULL
);
12768 memset(&desc
, 0, sizeof(desc
));
12769 desc
.dwSize
= desc_sizes
[j
];
12770 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
12771 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
12772 hr
= IDirectDrawSurface2_Lock(surface2
, NULL
, &desc
.desc1
, 0, 0);
12773 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
12774 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
12775 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
12776 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
12777 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
12778 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
12779 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
12782 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
12783 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
12784 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
12785 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
12786 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
12787 todo_wine_if(!expected_texture_stage
)
12788 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
12789 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
12790 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
12791 IDirectDrawSurface2_Unlock(surface2
, NULL
);
12794 memset(&desc
, 0, sizeof(desc
));
12795 desc
.dwSize
= desc_sizes
[j
];
12796 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
12797 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
12798 hr
= IDirectDrawSurface7_Lock(surface7
, NULL
, &desc
.desc2
, 0, 0);
12799 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
12800 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
12801 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
12802 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
12803 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
12804 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
12805 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
12808 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
12809 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
12810 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
12811 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
12812 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
12813 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
12814 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
12815 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
12816 IDirectDrawSurface7_Unlock(surface7
, NULL
);
12820 IDirectDrawSurface7_Release(surface7
);
12821 IDirectDrawSurface2_Release(surface2
);
12822 IDirectDrawSurface_Release(surface
);
12825 /* GetDisplayMode() */
12826 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
12828 memset(&desc
, 0xcc, sizeof(desc
));
12829 desc
.dwSize
= desc_sizes
[j
];
12830 expected_hr
= (desc
.dwSize
== sizeof(DDSURFACEDESC
) || desc
.dwSize
== sizeof(DDSURFACEDESC2
))
12831 ? DD_OK
: DDERR_INVALIDPARAMS
;
12832 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &desc
.desc1
);
12833 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, size %u.\n", hr
, expected_hr
, desc_sizes
[j
]);
12836 ok(desc
.dwSize
== sizeof(DDSURFACEDESC
), "Wrong size %u for %u.\n", desc
.dwSize
, desc_sizes
[j
]);
12837 ok(desc
.blob
[desc_sizes
[j
]] == 0xcc, "Overflow for size %u.\n", desc_sizes
[j
]);
12838 ok(desc
.blob
[desc_sizes
[j
] - 1] != 0xcc, "Struct not cleared for size %u.\n", desc_sizes
[j
]);
12842 refcount
= IDirectDraw2_Release(ddraw
);
12843 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
12846 static void test_ck_operation(void)
12848 IDirectDrawSurface2
*src
, *dst
;
12849 IDirectDrawSurface7
*src7
, *dst7
;
12850 IDirectDrawSurface
*surface1
;
12851 DDSURFACEDESC surface_desc
;
12852 IDirectDraw2
*ddraw
;
12861 window
= create_window();
12862 ddraw
= create_ddraw();
12863 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12864 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12865 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12867 memset(&surface_desc
, 0, sizeof(surface_desc
));
12868 surface_desc
.dwSize
= sizeof(surface_desc
);
12869 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12870 surface_desc
.dwWidth
= 4;
12871 surface_desc
.dwHeight
= 1;
12872 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12873 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12874 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
12875 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
12876 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
12877 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
12878 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
12879 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
12880 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&dst
);
12881 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#x.\n", hr
);
12882 IDirectDrawSurface_Release(surface1
);
12884 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
12885 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff00ff;
12886 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff00ff;
12887 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
12888 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
12889 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&src
);
12890 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#x.\n", hr
);
12891 IDirectDrawSurface_Release(surface1
);
12893 hr
= IDirectDrawSurface2_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12894 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12895 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
12896 color
= surface_desc
.lpSurface
;
12897 color
[0] = 0x77010203;
12898 color
[1] = 0x00010203;
12899 color
[2] = 0x77ff00ff;
12900 color
[3] = 0x00ff00ff;
12901 hr
= IDirectDrawSurface2_Unlock(src
, NULL
);
12902 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12904 for (i
= 0; i
< 2; ++i
)
12906 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12907 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12908 color
= surface_desc
.lpSurface
;
12909 color
[0] = 0xcccccccc;
12910 color
[1] = 0xcccccccc;
12911 color
[2] = 0xcccccccc;
12912 color
[3] = 0xcccccccc;
12913 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12914 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12918 hr
= IDirectDrawSurface2_BltFast(dst
, 0, 0, src
, NULL
, DDBLTFAST_SRCCOLORKEY
);
12919 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
12923 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, NULL
);
12924 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
12927 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
| DDLOCK_READONLY
, NULL
);
12928 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12929 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
12930 color
= surface_desc
.lpSurface
;
12931 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
12932 * color keying, but copy it to the destination surface. Others (sysmem surfaces) apply it for
12933 * color keying, but do not copy it into the destination surface. Nvidia neither uses it for
12934 * color keying nor copies it. */
12935 ok((color
[0] == 0x77010203 && color
[1] == 0x00010203
12936 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* AMD, Wine */
12937 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
12938 && color
[2] == 0x00ff00ff && color
[3] == 0xcccccccc) /* Sysmem surfaces? */
12939 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
12940 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Nvidia */
12941 || broken(color
[0] == 0xff010203 && color
[1] == 0xff010203
12942 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Testbot */,
12943 "Destination data after blitting is %08x %08x %08x %08x, i=%u.\n",
12944 color
[0], color
[1], color
[2], color
[3], i
);
12945 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
12946 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12949 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12950 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12951 ok(ckey
.dwColorSpaceLowValue
== 0x00ff00ff && ckey
.dwColorSpaceHighValue
== 0x00ff00ff,
12952 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12954 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
12955 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12956 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12958 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12959 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12960 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12961 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00 && ckey
.dwColorSpaceHighValue
== 0x0000ff00,
12962 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12964 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0;
12965 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0;
12966 hr
= IDirectDrawSurface2_GetSurfaceDesc(src
, &surface_desc
);
12967 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
12968 ok(surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0x0000ff00
12969 && surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0x0000ff00,
12970 "Got unexpected color key low=%08x high=%08x.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
12971 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
12973 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
12974 ckey
.dwColorSpaceLowValue
= 0x000000ff;
12975 ckey
.dwColorSpaceHighValue
= 0x00000000;
12976 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12977 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12979 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12980 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12981 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12982 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
12983 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12985 ckey
.dwColorSpaceLowValue
= 0x000000ff;
12986 ckey
.dwColorSpaceHighValue
= 0x00000001;
12987 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12988 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12990 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12991 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12992 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12993 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
12994 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12996 ckey
.dwColorSpaceLowValue
= 0x000000fe;
12997 ckey
.dwColorSpaceHighValue
= 0x000000fd;
12998 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12999 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13001 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13002 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13003 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
13004 ok(ckey
.dwColorSpaceLowValue
== 0x000000fe && ckey
.dwColorSpaceHighValue
== 0x000000fe,
13005 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13007 IDirectDrawSurface2_Release(src
);
13008 IDirectDrawSurface2_Release(dst
);
13010 /* Test source and destination keys and where they are read from. Use a surface with alpha
13011 * to avoid driver-dependent content in the X channel. */
13012 memset(&surface_desc
, 0, sizeof(surface_desc
));
13013 surface_desc
.dwSize
= sizeof(surface_desc
);
13014 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
13015 surface_desc
.dwWidth
= 6;
13016 surface_desc
.dwHeight
= 1;
13017 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13018 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
13019 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
13020 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
13021 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
13022 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
13023 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
13024 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
13025 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13026 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&dst
);
13027 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#x.\n", hr
);
13028 IDirectDrawSurface_Release(surface1
);
13030 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
13031 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13032 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&src
);
13033 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#x.\n", hr
);
13034 IDirectDrawSurface_Release(surface1
);
13036 ckey
.dwColorSpaceLowValue
= 0x0000ff00;
13037 ckey
.dwColorSpaceHighValue
= 0x0000ff00;
13038 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
13039 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13040 ckey
.dwColorSpaceLowValue
= 0x00ff0000;
13041 ckey
.dwColorSpaceHighValue
= 0x00ff0000;
13042 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_DESTBLT
, &ckey
);
13043 ok(SUCCEEDED(hr
) || hr
== DDERR_NOCOLORKEYHW
, "Failed to set color key, hr %#x.\n", hr
);
13046 /* Nvidia reject dest keys, AMD allows them. This applies to vidmem and sysmem surfaces. */
13047 skip("Failed to set destination color key, skipping related tests.\n");
13051 ckey
.dwColorSpaceLowValue
= 0x000000ff;
13052 ckey
.dwColorSpaceHighValue
= 0x000000ff;
13053 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13054 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13055 ckey
.dwColorSpaceLowValue
= 0x000000aa;
13056 ckey
.dwColorSpaceHighValue
= 0x000000aa;
13057 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
13058 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13060 memset(&fx
, 0, sizeof(fx
));
13061 fx
.dwSize
= sizeof(fx
);
13062 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x00110000;
13063 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x00110000;
13064 fx
.ddckDestColorkey
.dwColorSpaceHighValue
= 0x00001100;
13065 fx
.ddckDestColorkey
.dwColorSpaceLowValue
= 0x00001100;
13067 hr
= IDirectDrawSurface2_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13068 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13069 color
= surface_desc
.lpSurface
;
13070 color
[0] = 0x000000ff; /* Applies to src blt key in src surface. */
13071 color
[1] = 0x000000aa; /* Applies to dst blt key in src surface. */
13072 color
[2] = 0x00ff0000; /* Dst color key in dst surface. */
13073 color
[3] = 0x0000ff00; /* Src color key in dst surface. */
13074 color
[4] = 0x00001100; /* Src color key in ddbltfx. */
13075 color
[5] = 0x00110000; /* Dst color key in ddbltfx. */
13076 hr
= IDirectDrawSurface2_Unlock(src
, NULL
);
13077 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13079 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13080 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13081 color
= surface_desc
.lpSurface
;
13082 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13083 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13084 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13086 /* Test a blit without keying. */
13087 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, 0, &fx
);
13088 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13090 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13091 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13092 color
= surface_desc
.lpSurface
;
13093 /* Should have copied src data unmodified to dst. */
13094 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13095 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13096 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13097 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13099 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13100 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13101 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13104 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
13105 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13107 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13108 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13109 color
= surface_desc
.lpSurface
;
13110 /* Src key applied to color[0]. It is unmodified, the others are copied. */
13111 ok(color
[0] == 0x55555555 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13112 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13113 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13114 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13116 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13117 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13118 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13120 /* Src override. */
13121 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, &fx
);
13122 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13124 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13125 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13126 color
= surface_desc
.lpSurface
;
13127 /* Override key applied to color[5]. It is unmodified, the others are copied. */
13128 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13129 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x55555555,
13130 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13131 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13133 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13134 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13135 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13137 /* Src override AND src key. That is not supposed to work. */
13138 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_KEYSRCOVERRIDE
, &fx
);
13139 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13141 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13142 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13143 color
= surface_desc
.lpSurface
;
13144 /* Ensure the destination was not changed. */
13145 ok(color
[0] == 0x55555555 && color
[1] == 0x55555555 && color
[2] == 0x55555555 &&
13146 color
[3] == 0x55555555 && color
[4] == 0x55555555 && color
[5] == 0x55555555,
13147 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13148 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13150 /* Use different dst colors for the dst key test. */
13151 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13152 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13153 color
[2] = 0x00001100; /* Dest key in override. */
13154 color
[3] = 0x00001100; /* Dest key in override. */
13155 color
[4] = 0x000000aa; /* Dest key in src surface. */
13156 color
[5] = 0x000000aa; /* Dest key in src surface. */
13157 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13158 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13160 /* Dest key blit. The key is taken from the SOURCE surface in v2! */
13161 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13162 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13164 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13165 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13166 color
= surface_desc
.lpSurface
;
13167 /* Dst key applied to color[4,5], they are the only changed pixels. */
13168 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
13169 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13170 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13171 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13173 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13174 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13175 color
[2] = 0x00001100; /* Dest key in override. */
13176 color
[3] = 0x00001100; /* Dest key in override. */
13177 color
[4] = 0x000000aa; /* Dest key in src surface. */
13178 color
[5] = 0x000000aa; /* Dest key in src surface. */
13179 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13180 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13182 /* What happens with a QI'd newer version of the interface? It takes the key
13183 * from the destination surface. */
13184 hr
= IDirectDrawSurface2_QueryInterface(src
, &IID_IDirectDrawSurface7
, (void **)&src7
);
13185 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
13186 hr
= IDirectDrawSurface2_QueryInterface(dst
, &IID_IDirectDrawSurface7
, (void **)&dst7
);
13187 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
13189 hr
= IDirectDrawSurface7_Blt(dst7
, NULL
, src7
, NULL
, DDBLT_KEYDEST
, &fx
);
13190 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13192 IDirectDrawSurface7_Release(dst7
);
13193 IDirectDrawSurface7_Release(src7
);
13195 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13196 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13197 color
= surface_desc
.lpSurface
;
13198 /* Dst key applied to color[0,1], they are the only changed pixels. */
13199 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
13200 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13201 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13202 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13204 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13205 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13206 color
[2] = 0x00001100; /* Dest key in override. */
13207 color
[3] = 0x00001100; /* Dest key in override. */
13208 color
[4] = 0x000000aa; /* Dest key in src surface. */
13209 color
[5] = 0x000000aa; /* Dest key in src surface. */
13210 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13211 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13213 /* Dest override key blit. */
13214 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, &fx
);
13215 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13217 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13218 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13219 color
= surface_desc
.lpSurface
;
13220 /* Dst key applied to color[2,3], they are the only changed pixels. */
13221 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00ff0000 &&
13222 color
[3] == 0x0000ff00 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13223 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13224 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13226 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13227 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13228 color
[2] = 0x00001100; /* Dest key in override. */
13229 color
[3] = 0x00001100; /* Dest key in override. */
13230 color
[4] = 0x000000aa; /* Dest key in src surface. */
13231 color
[5] = 0x000000aa; /* Dest key in src surface. */
13232 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13233 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13235 /* Dest override together with surface key. Supposed to fail. */
13236 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYDESTOVERRIDE
, &fx
);
13237 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13239 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13240 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13241 color
= surface_desc
.lpSurface
;
13242 /* Destination is unchanged. */
13243 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
13244 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13245 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13246 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13247 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13248 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13250 /* Source and destination key. This is driver dependent. New HW treats it like
13251 * DDBLT_KEYSRC. Older HW and some software renderers apply both keys. */
13254 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYSRC
, &fx
);
13255 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13257 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13258 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13259 color
= surface_desc
.lpSurface
;
13260 /* Color[0] is filtered by the src key, 2-5 are filtered by the dst key, if
13261 * the driver applies it. */
13262 ok(color
[0] == 0x00ff0000 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13263 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13264 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13265 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13267 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13268 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13269 color
[2] = 0x00001100; /* Dest key in override. */
13270 color
[3] = 0x00001100; /* Dest key in override. */
13271 color
[4] = 0x000000aa; /* Dest key in src surface. */
13272 color
[5] = 0x000000aa; /* Dest key in src surface. */
13273 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13274 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13277 /* Override keys without ddbltfx parameter fail */
13278 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, NULL
);
13279 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13280 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, NULL
);
13281 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13283 /* Try blitting without keys in the source surface. */
13284 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
13285 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13286 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_DESTBLT
, NULL
);
13287 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13289 /* That fails now. Do not bother to check that the data is unmodified. */
13290 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
13291 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13293 /* Surprisingly this still works. It uses the old key from the src surface. */
13294 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13295 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13297 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13298 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13299 color
= surface_desc
.lpSurface
;
13300 /* Dst key applied to color[4,5], they are the only changed pixels. */
13301 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
13302 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13303 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13304 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13305 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13306 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13308 /* This returns DDERR_NOCOLORKEY as expected. */
13309 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
13310 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
13312 /* GetSurfaceDesc returns a zeroed key as expected. */
13313 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x12345678;
13314 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x12345678;
13315 hr
= IDirectDrawSurface2_GetSurfaceDesc(src
, &surface_desc
);
13316 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
13317 ok(!surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
13318 && !surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
,
13319 "Got unexpected color key low=%08x high=%08x.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
13320 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
13322 /* Try blitting without keys in the destination surface. */
13323 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_SRCBLT
, NULL
);
13324 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13325 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_DESTBLT
, NULL
);
13326 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13328 /* This fails, as sanity would dictate. */
13329 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13330 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13333 IDirectDrawSurface2_Release(src
);
13334 IDirectDrawSurface2_Release(dst
);
13335 refcount
= IDirectDraw2_Release(ddraw
);
13336 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
13337 DestroyWindow(window
);
13340 static void test_set_render_state(void)
13342 IDirect3DDevice2
*device
;
13343 IDirectDraw2
*ddraw
;
13349 window
= create_window();
13350 ddraw
= create_ddraw();
13351 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13352 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13354 skip("Failed to create 3D device.\n");
13355 DestroyWindow(window
);
13359 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, TRUE
);
13360 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13361 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, FALSE
);
13362 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13364 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
13365 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13366 state
= 0xdeadbeef;
13367 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, &state
);
13368 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13369 ok(!state
, "Got unexpected render state %#x.\n", state
);
13370 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
13371 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13372 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &state
);
13373 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13374 ok(state
== D3DTBLEND_MODULATE
, "Got unexpected render state %#x.\n", state
);
13376 refcount
= IDirect3DDevice2_Release(device
);
13377 ok(!refcount
, "Device has %u references left.\n", refcount
);
13378 refcount
= IDirectDraw2_Release(ddraw
);
13379 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
13380 DestroyWindow(window
);
13383 static void test_depth_readback(void)
13385 DWORD depth
, expected_depth
, max_diff
, passed_fmts
= 0;
13386 IDirect3DMaterial2
*blue_background
;
13387 IDirectDrawSurface
*rt
, *ds
;
13388 IDirect3DViewport2
*viewport
;
13389 DDSURFACEDESC surface_desc
;
13390 IDirect3DDevice2
*device
;
13391 unsigned int i
, x
, y
;
13392 IDirectDraw2
*ddraw
;
13399 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
13400 static D3DLVERTEX quad
[] =
13402 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xff00ff00}},
13403 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
13404 {{ 1.0f
}, {-1.0f
}, {1.0f
}, 0, {0xff00ff00}},
13405 {{ 1.0f
}, { 1.0f
}, {0.9f
}, 0, {0xff00ff00}},
13408 static const struct
13410 unsigned int z_depth
, z_mask
;
13419 window
= create_window();
13420 ok(!!window
, "Failed to create a window.\n");
13421 ddraw
= create_ddraw();
13422 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13423 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13425 skip("Failed to create a D3D device, skipping tests.\n");
13426 IDirectDraw2_Release(ddraw
);
13427 DestroyWindow(window
);
13431 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
13432 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
13433 blue_background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
13434 viewport
= create_viewport(device
, 0, 0, 640, 480);
13435 viewport_set_background(device
, viewport
, blue_background
);
13436 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
13437 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
13439 ds
= get_depth_stencil(device
);
13440 hr
= IDirectDrawSurface_DeleteAttachedSurface(rt
, 0, ds
);
13441 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
13442 IDirectDrawSurface_Release(ds
);
13444 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
13446 memset(&surface_desc
, 0, sizeof(surface_desc
));
13447 surface_desc
.dwSize
= sizeof(surface_desc
);
13448 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
13449 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
;
13450 U2(surface_desc
).dwZBufferBitDepth
= tests
[i
].z_depth
;
13451 surface_desc
.dwWidth
= 640;
13452 surface_desc
.dwHeight
= 480;
13453 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
13456 skip("Format %u not supported, skipping test.\n", i
);
13460 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
13461 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
13462 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
13463 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
13465 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
13466 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13467 hr
= IDirect3DDevice2_BeginScene(device
);
13468 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
13469 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
13470 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13471 hr
= IDirect3DDevice2_EndScene(device
);
13472 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
13474 memset(&surface_desc
, 0, sizeof(surface_desc
));
13475 surface_desc
.dwSize
= sizeof(surface_desc
);
13476 hr
= IDirectDrawSurface_Lock(ds
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13477 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13480 for (y
= 60; y
< 480; y
+= 120)
13482 for (x
= 80; x
< 640; x
+= 160)
13484 ptr
= (BYTE
*)surface_desc
.lpSurface
13485 + y
* U1(surface_desc
).lPitch
13486 + x
* (tests
[i
].z_depth
== 16 ? 2 : 4);
13487 depth
= *((DWORD
*)ptr
) & tests
[i
].z_mask
;
13488 expected_depth
= (x
* (0.9 / 640.0) + y
* (0.1 / 480.0)) * tests
[i
].z_mask
;
13489 max_diff
= ((0.5f
* 0.9f
) / 640.0f
) * tests
[i
].z_mask
;
13490 /* The ddraw2 version of this test behaves similarly to the ddraw7 version on Nvidia GPUs,
13491 * except that we only have D16 (broken on geforce 9) and D24X8 (broken on geforce 7) available.
13492 * Accept all nvidia GPUs as broken here, but still expect one of the formats to pass. */
13493 ok(compare_uint(expected_depth
, depth
, max_diff
) || ddraw_is_nvidia(ddraw
),
13494 "Test %u: Got depth 0x%08x (diff %d), expected 0x%08x+/-%u, at %u, %u.\n",
13495 i
, depth
, expected_depth
- depth
, expected_depth
, max_diff
, x
, y
);
13496 if (!compare_uint(expected_depth
, depth
, max_diff
))
13501 hr
= IDirectDrawSurface_Unlock(ds
, NULL
);
13502 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13507 hr
= IDirectDrawSurface_DeleteAttachedSurface(rt
, 0, ds
);
13508 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
13509 IDirectDrawSurface_Release(ds
);
13512 ok(passed_fmts
, "Not a single format passed the tests, this is bad even by Nvidia's standards.\n");
13514 destroy_viewport(device
, viewport
);
13515 destroy_material(blue_background
);
13516 IDirectDrawSurface_Release(rt
);
13517 refcount
= IDirect3DDevice2_Release(device
);
13518 ok(!refcount
, "Device has %u references left.\n", refcount
);
13519 IDirectDraw2_Release(ddraw
);
13520 DestroyWindow(window
);
13523 static void test_clear(void)
13525 D3DRECT rect_negneg
, rect_full
= {{0}, {0}, {640}, {480}};
13526 IDirect3DViewport2
*viewport
, *viewport2
, *viewport3
;
13527 IDirect3DMaterial2
*white
, *red
, *green
, *blue
;
13528 IDirect3DDevice2
*device
;
13529 IDirectDrawSurface
*rt
;
13530 IDirectDraw2
*ddraw
;
13537 window
= create_window();
13538 ddraw
= create_ddraw();
13539 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13540 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13542 skip("Failed to create a 3D device, skipping test.\n");
13543 IDirectDraw2_Release(ddraw
);
13544 DestroyWindow(window
);
13547 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
13548 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
13550 viewport
= create_viewport(device
, 0, 0, 640, 480);
13551 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
13552 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
13554 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
13555 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
13556 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
13557 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
13559 viewport_set_background(device
, viewport
, white
);
13560 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13561 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13563 /* Positive x, negative y. */
13564 U1(rect
[0]).x1
= 0;
13565 U2(rect
[0]).y1
= 480;
13566 U3(rect
[0]).x2
= 320;
13567 U4(rect
[0]).y2
= 240;
13569 /* Positive x, positive y. */
13570 U1(rect
[1]).x1
= 0;
13571 U2(rect
[1]).y1
= 0;
13572 U3(rect
[1]).x2
= 320;
13573 U4(rect
[1]).y2
= 240;
13575 /* Clear 2 rectangles with one call. Unlike d3d8/9, the refrast does not
13576 * refuse negative rectangles, but it will not clear them either. */
13577 viewport_set_background(device
, viewport
, red
);
13578 hr
= IDirect3DViewport2_Clear(viewport
, 2, rect
, D3DCLEAR_TARGET
);
13579 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13581 color
= get_surface_color(rt
, 160, 360);
13582 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 3 (pos, neg) has color 0x%08x.\n", color
);
13583 color
= get_surface_color(rt
, 160, 120);
13584 ok(compare_color(color
, 0x00ff0000, 0), "Clear rectangle 1 (pos, pos) has color 0x%08x.\n", color
);
13585 color
= get_surface_color(rt
, 480, 360);
13586 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (NULL) has color 0x%08x.\n", color
);
13587 color
= get_surface_color(rt
, 480, 120);
13588 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (neg, neg) has color 0x%08x.\n", color
);
13590 viewport_set_background(device
, viewport
, white
);
13591 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13592 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13594 /* negative x, negative y.
13595 * Also ignored, except on WARP, which clears the entire screen. */
13596 U1(rect_negneg
).x1
= 640;
13597 U2(rect_negneg
).y1
= 240;
13598 U3(rect_negneg
).x2
= 320;
13599 U4(rect_negneg
).y2
= 0;
13600 viewport_set_background(device
, viewport
, green
);
13601 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_negneg
, D3DCLEAR_TARGET
);
13602 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13604 color
= get_surface_color(rt
, 160, 360);
13605 ok(compare_color(color
, 0x00ffffff, 0)
13606 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
13607 "Got unexpected color 0x%08x.\n", color
);
13608 color
= get_surface_color(rt
, 160, 120);
13609 ok(compare_color(color
, 0x00ffffff, 0)
13610 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
13611 "Got unexpected color 0x%08x.\n", color
);
13612 color
= get_surface_color(rt
, 480, 360);
13613 ok(compare_color(color
, 0x00ffffff, 0)
13614 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
13615 "Got unexpected color 0x%08x.\n", color
);
13616 color
= get_surface_color(rt
, 480, 120);
13617 ok(compare_color(color
, 0x00ffffff, 0)
13618 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
13619 "Got unexpected color 0x%08x.\n", color
);
13621 /* Test how the viewport affects clears. */
13622 viewport_set_background(device
, viewport
, white
);
13623 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13624 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13626 viewport2
= create_viewport(device
, 160, 120, 160, 120);
13627 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
13628 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
13630 viewport_set_background(device
, viewport2
, blue
);
13631 hr
= IDirect3DViewport2_Clear(viewport2
, 1, &rect_full
, D3DCLEAR_TARGET
);
13632 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13634 viewport3
= create_viewport(device
, 320, 240, 320, 240);
13635 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport3
);
13636 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
13638 U1(rect
[0]).x1
= 160;
13639 U2(rect
[0]).y1
= 120;
13640 U3(rect
[0]).x2
= 480;
13641 U4(rect
[0]).y2
= 360;
13642 viewport_set_background(device
, viewport3
, green
);
13643 hr
= IDirect3DViewport2_Clear(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
);
13644 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13646 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
13647 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
13649 color
= get_surface_color(rt
, 158, 118);
13650 ok(compare_color(color
, 0x00ffffff, 0), "(158, 118) has color 0x%08x.\n", color
);
13651 color
= get_surface_color(rt
, 162, 118);
13652 ok(compare_color(color
, 0x00ffffff, 0), "(162, 118) has color 0x%08x.\n", color
);
13653 color
= get_surface_color(rt
, 158, 122);
13654 ok(compare_color(color
, 0x00ffffff, 0), "(158, 122) has color 0x%08x.\n", color
);
13655 color
= get_surface_color(rt
, 162, 122);
13656 ok(compare_color(color
, 0x000000ff, 0), "(162, 122) has color 0x%08x.\n", color
);
13658 color
= get_surface_color(rt
, 318, 238);
13659 ok(compare_color(color
, 0x000000ff, 0), "(318, 238) has color 0x%08x.\n", color
);
13660 color
= get_surface_color(rt
, 322, 238);
13661 ok(compare_color(color
, 0x00ffffff, 0), "(322, 238) has color 0x%08x.\n", color
);
13662 color
= get_surface_color(rt
, 318, 242);
13663 ok(compare_color(color
, 0x00ffffff, 0), "(318, 242) has color 0x%08x.\n", color
);
13664 color
= get_surface_color(rt
, 322, 242);
13665 ok(compare_color(color
, 0x0000ff00, 0), "(322, 242) has color 0x%08x.\n", color
);
13667 color
= get_surface_color(rt
, 478, 358);
13668 ok(compare_color(color
, 0x0000ff00, 0), "(478, 358) has color 0x%08x.\n", color
);
13669 color
= get_surface_color(rt
, 482, 358);
13670 ok(compare_color(color
, 0x00ffffff, 0), "(482, 358) has color 0x%08x.\n", color
);
13671 color
= get_surface_color(rt
, 478, 362);
13672 ok(compare_color(color
, 0x00ffffff, 0), "(478, 362) has color 0x%08x.\n", color
);
13673 color
= get_surface_color(rt
, 482, 362);
13674 ok(compare_color(color
, 0x00ffffff, 0), "(482, 362) has color 0x%08x.\n", color
);
13676 /* The clear rectangle is rendertarget absolute, not relative to the
13678 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13679 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13680 U1(rect
[0]).x1
= 330;
13681 U2(rect
[0]).y1
= 250;
13682 U3(rect
[0]).x2
= 340;
13683 U4(rect
[0]).y2
= 260;
13684 hr
= IDirect3DViewport2_Clear(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
);
13685 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13687 color
= get_surface_color(rt
, 328, 248);
13688 ok(compare_color(color
, 0x00ffffff, 0), "(328, 248) has color 0x%08x.\n", color
);
13689 color
= get_surface_color(rt
, 332, 248);
13690 ok(compare_color(color
, 0x00ffffff, 0), "(332, 248) has color 0x%08x.\n", color
);
13691 color
= get_surface_color(rt
, 328, 252);
13692 ok(compare_color(color
, 0x00ffffff, 0), "(328, 252) has color 0x%08x.\n", color
);
13693 color
= get_surface_color(rt
, 332, 252);
13694 ok(compare_color(color
, 0x0000ff00, 0), "(332, 252) has color 0x%08x.\n", color
);
13696 color
= get_surface_color(rt
, 338, 248);
13697 ok(compare_color(color
, 0x00ffffff, 0), "(338, 248) has color 0x%08x.\n", color
);
13698 color
= get_surface_color(rt
, 342, 248);
13699 ok(compare_color(color
, 0x00ffffff, 0), "(342, 248) has color 0x%08x.\n", color
);
13700 color
= get_surface_color(rt
, 338, 252);
13701 ok(compare_color(color
, 0x0000ff00, 0), "(338, 252) has color 0x%08x.\n", color
);
13702 color
= get_surface_color(rt
, 342, 252);
13703 ok(compare_color(color
, 0x00ffffff, 0), "(342, 252) has color 0x%08x.\n", color
);
13705 color
= get_surface_color(rt
, 328, 258);
13706 ok(compare_color(color
, 0x00ffffff, 0), "(328, 258) has color 0x%08x.\n", color
);
13707 color
= get_surface_color(rt
, 332, 258);
13708 ok(compare_color(color
, 0x0000ff00, 0), "(332, 258) has color 0x%08x.\n", color
);
13709 color
= get_surface_color(rt
, 328, 262);
13710 ok(compare_color(color
, 0x00ffffff, 0), "(328, 262) has color 0x%08x.\n", color
);
13711 color
= get_surface_color(rt
, 332, 262);
13712 ok(compare_color(color
, 0x00ffffff, 0), "(332, 262) has color 0x%08x.\n", color
);
13714 color
= get_surface_color(rt
, 338, 258);
13715 ok(compare_color(color
, 0x0000ff00, 0), "(338, 258) has color 0x%08x.\n", color
);
13716 color
= get_surface_color(rt
, 342, 258);
13717 ok(compare_color(color
, 0x00ffffff, 0), "(342, 258) has color 0x%08x.\n", color
);
13718 color
= get_surface_color(rt
, 338, 262);
13719 ok(compare_color(color
, 0x00ffffff, 0), "(338, 262) has color 0x%08x.\n", color
);
13720 color
= get_surface_color(rt
, 342, 262);
13721 ok(compare_color(color
, 0x00ffffff, 0), "(342, 262) has color 0x%08x.\n", color
);
13723 /* COLORWRITEENABLE, SRGBWRITEENABLE and scissor rectangles do not exist
13726 IDirect3DViewport2_Release(viewport3
);
13727 IDirect3DViewport2_Release(viewport2
);
13728 IDirect3DViewport2_Release(viewport
);
13729 IDirect3DMaterial2_Release(white
);
13730 IDirect3DMaterial2_Release(red
);
13731 IDirect3DMaterial2_Release(green
);
13732 IDirect3DMaterial2_Release(blue
);
13733 IDirectDrawSurface_Release(rt
);
13734 refcount
= IDirect3DDevice2_Release(device
);
13735 ok(!refcount
, "Device has %u references left.\n", refcount
);
13736 refcount
= IDirectDraw2_Release(ddraw
);
13737 ok(!refcount
, "Ddraw object has %u references left.\n", refcount
);
13738 DestroyWindow(window
);
13741 struct enum_surfaces_param
13743 IDirectDraw2
*ddraw
;
13744 DDSURFACEDESC modes
[20];
13745 unsigned int mode_count
;
13747 IDirectDrawSurface
*surfaces
[8];
13748 unsigned int count
;
13751 static HRESULT CALLBACK
build_mode_list_cb(DDSURFACEDESC
*desc
, void *context
)
13753 struct enum_surfaces_param
*param
= context
;
13754 IDirectDrawSurface
*surface
;
13756 if (SUCCEEDED(IDirectDraw2_CreateSurface(param
->ddraw
, desc
, &surface
, NULL
)))
13758 if (param
->mode_count
< ARRAY_SIZE(param
->modes
))
13759 param
->modes
[param
->mode_count
] = *desc
;
13760 ++param
->mode_count
;
13761 IDirectDrawSurface_Release(surface
);
13764 return DDENUMRET_OK
;
13767 static HRESULT WINAPI
enum_surfaces_cb(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
13769 struct enum_surfaces_param
*param
= context
;
13770 BOOL found
= FALSE
;
13773 for (i
= 0; i
< ARRAY_SIZE(param
->surfaces
); ++i
)
13775 if (param
->surfaces
[i
] == surface
)
13782 ok(found
, "Unexpected surface %p enumerated.\n", surface
);
13783 IDirectDrawSurface_Release(surface
);
13786 return DDENUMRET_OK
;
13789 static HRESULT WINAPI
enum_surfaces_create_cb(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
13791 static const DWORD expect_flags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_PIXELFORMAT
;
13792 struct enum_surfaces_param
*param
= context
;
13794 ok(!surface
, "Unexpected surface %p.\n", surface
);
13795 ok((desc
->dwFlags
& expect_flags
) == expect_flags
, "Got unexpected flags %#x.\n", desc
->dwFlags
);
13796 if (param
->count
< ARRAY_SIZE(param
->modes
))
13798 const DDSURFACEDESC
*expect
= ¶m
->modes
[param
->count
];
13799 ok(desc
->dwWidth
== expect
->dwWidth
, "Expected width %u, got %u.\n", expect
->dwWidth
, desc
->dwWidth
);
13800 ok(desc
->dwHeight
== expect
->dwHeight
, "Expected height %u, got %u.\n", expect
->dwHeight
, desc
->dwHeight
);
13801 ok(!memcmp(&U4(*desc
).ddpfPixelFormat
, &U4(*expect
).ddpfPixelFormat
, sizeof(U4(*desc
).ddpfPixelFormat
)),
13802 "Pixel formats didn't match.\n");
13807 return DDENUMRET_OK
;
13810 static void test_enum_surfaces(void)
13812 struct enum_surfaces_param param
= {0};
13813 DDPIXELFORMAT current_format
;
13814 IDirectDraw2
*ddraw
;
13815 DDSURFACEDESC desc
;
13818 ddraw
= create_ddraw();
13819 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13820 param
.ddraw
= ddraw
;
13822 memset(&desc
, 0, sizeof(desc
));
13823 desc
.dwSize
= sizeof(desc
);
13824 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &desc
);
13825 ok(hr
== DD_OK
, "Failed to get display mode, hr %#x.\n", hr
);
13826 current_format
= desc
.ddpfPixelFormat
;
13828 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
13829 ok(hr
== DD_OK
, "Failed to set cooperative level, hr %#x.\n", hr
);
13831 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
, NULL
, NULL
, enum_surfaces_cb
);
13832 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13834 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
13835 NULL
, NULL
, enum_surfaces_cb
);
13836 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13838 memset(&desc
, 0, sizeof(desc
));
13839 desc
.dwSize
= sizeof(desc
);
13840 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
13841 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
13842 U2(desc
).dwMipMapCount
= 3;
13844 desc
.dwHeight
= 32;
13845 hr
= IDirectDraw2_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
13846 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
13848 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[0], &desc
.ddsCaps
, ¶m
.surfaces
[1]);
13849 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
13850 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[1], &desc
.ddsCaps
, ¶m
.surfaces
[2]);
13851 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
13852 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[2], &desc
.ddsCaps
, ¶m
.surfaces
[3]);
13853 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
13854 ok(!param
.surfaces
[3], "Got unexpected pointer %p.\n", param
.surfaces
[3]);
13857 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
13858 &desc
, ¶m
, enum_surfaces_cb
);
13859 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#x.\n", hr
);
13860 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13863 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
13864 NULL
, ¶m
, enum_surfaces_cb
);
13865 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#x.\n", hr
);
13866 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13868 desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
;
13870 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
13871 &desc
, ¶m
, enum_surfaces_cb
);
13872 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
13873 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13876 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_NOMATCH
,
13877 &desc
, ¶m
, enum_surfaces_cb
);
13878 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
13879 ok(param
.count
== 2, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13883 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
13884 &desc
, ¶m
, enum_surfaces_cb
);
13885 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
13886 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13890 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
, &desc
, ¶m
, enum_surfaces_cb
);
13891 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
13892 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13894 IDirectDrawSurface_Release(param
.surfaces
[2]);
13895 IDirectDrawSurface_Release(param
.surfaces
[1]);
13896 IDirectDrawSurface_Release(param
.surfaces
[0]);
13899 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
13900 NULL
, ¶m
, enum_surfaces_cb
);
13901 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
13902 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13904 memset(&desc
, 0, sizeof(desc
));
13905 desc
.dwSize
= sizeof(desc
);
13906 desc
.dwFlags
= DDSD_CAPS
;
13907 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
13909 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
13910 &desc
, ¶m
, enum_surfaces_create_cb
);
13911 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
13913 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_NOMATCH
,
13914 &desc
, ¶m
, enum_surfaces_create_cb
);
13915 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
13917 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
,
13918 &desc
, ¶m
, enum_surfaces_create_cb
);
13919 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
13921 /* When not passed width and height, the callback is called with every
13922 * available display resolution. */
13924 param
.mode_count
= 0;
13925 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
13926 U4(desc
).ddpfPixelFormat
= current_format
;
13927 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, 0, &desc
, ¶m
, build_mode_list_cb
);
13928 ok(hr
== DD_OK
, "Failed to build mode list, hr %#x.\n", hr
);
13931 desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
13932 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
13933 &desc
, ¶m
, enum_surfaces_create_cb
);
13934 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
13935 ok(param
.count
== param
.mode_count
, "Expected %u surfaces, got %u.\n", param
.mode_count
, param
.count
);
13937 desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
13938 desc
.dwWidth
= desc
.dwHeight
= 32;
13940 param
.modes
[0].dwWidth
= param
.modes
[0].dwHeight
= 32;
13943 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
13944 &desc
, ¶m
, enum_surfaces_create_cb
);
13945 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
13946 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13948 hr
= IDirectDraw2_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
13949 ok(hr
== DD_OK
, "Failed to create surface, hr %#x.\n", hr
);
13951 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
13952 &desc
, ¶m
, enum_surfaces_create_cb
);
13953 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
13954 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13955 IDirectDrawSurface2_Release(param
.surfaces
[0]);
13957 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
13958 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
13959 desc
.ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
13960 desc
.ddpfPixelFormat
.dwFourCC
= 0xdeadbeef;
13963 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
13964 &desc
, ¶m
, enum_surfaces_create_cb
);
13965 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
13966 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13968 IDirectDraw2_Release(ddraw
);
13971 static void test_viewport(void)
13976 RECT expected_rect
;
13977 const char *message
;
13981 {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
13982 {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
13983 {{ 0, 0, 1280, 960}, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
13984 {{ 0, 0, 2000, 1600}, { 0, 400, 639, 479}, "Viewport (0, 0) - (2000, 1600)"},
13985 {{100, 100, 640, 480}, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
13986 {{ 0, 0, 8192, 8192}, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
13988 static const struct vec2 rt_sizes
[] =
13990 {640, 480}, {1280, 960}, {320, 240}, {800, 600},
13992 static D3DMATRIX mat
=
13994 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13995 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13996 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13997 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13999 static D3DLVERTEX quad
[] =
14001 {{-1.5f
}, {-0.5f
}, {0.1f
}, 0, {0xffffffff}},
14002 {{-1.5f
}, { 0.5f
}, {0.1f
}, 0, {0xffffffff}},
14003 {{ 0.5f
}, {-0.5f
}, {0.1f
}, 0, {0xffffffff}},
14004 {{ 0.5f
}, { 0.5f
}, {0.1f
}, 0, {0xffffffff}},
14006 IDirect3DViewport2
*viewport
, *full_viewport
;
14007 IDirect3DMaterial2
*black_background
;
14008 IDirectDrawSurface
*rt
, *ds
;
14009 DDSURFACEDESC surface_desc
;
14010 IDirect3DDevice2
*device
;
14011 BOOL expected_failure
;
14012 IDirectDraw2
*ddraw
;
14013 DDPIXELFORMAT z_fmt
;
14014 D3DRECT clear_rect
;
14022 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
14023 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
14024 ddraw
= create_ddraw();
14025 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14026 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
14028 skip("Failed to create a 3D device, skipping test.\n");
14029 IDirectDraw2_Release(ddraw
);
14030 DestroyWindow(window
);
14034 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
14035 ok(SUCCEEDED(hr
), "Failed to get Direct3D2 interface, hr %#x.\n", hr
);
14037 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
14038 ok(SUCCEEDED(hr
), "Failed to disable depth test, hr %#x.\n", hr
);
14039 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
14040 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
14042 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
14043 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
14044 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
14045 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
14046 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
14047 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
14049 black_background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
14051 ds
= get_depth_stencil(device
);
14052 memset(&surface_desc
, 0, sizeof(surface_desc
));
14053 surface_desc
.dwSize
= sizeof(surface_desc
);
14054 hr
= IDirectDrawSurface_GetSurfaceDesc(ds
, &surface_desc
);
14055 z_fmt
= surface_desc
.ddpfPixelFormat
;
14057 for (i
= 0; i
< ARRAY_SIZE(rt_sizes
); ++i
)
14061 memset(&surface_desc
, 0, sizeof(surface_desc
));
14062 surface_desc
.dwSize
= sizeof(surface_desc
);
14063 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
14064 surface_desc
.dwWidth
= rt_sizes
[i
].x
;
14065 surface_desc
.dwHeight
= rt_sizes
[i
].y
;
14066 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
14067 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
14068 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x (i %u).\n", hr
, i
);
14070 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
14071 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
14072 surface_desc
.ddpfPixelFormat
= z_fmt
;
14073 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
14074 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x (i %u).\n", hr
, i
);
14075 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
14076 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x (i %u).\n", hr
, i
);
14078 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
14079 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x (i %u).\n", hr
, i
);
14083 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
14084 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
14087 full_viewport
= create_viewport(device
, 0, 0, rt_sizes
[i
].x
, rt_sizes
[i
].y
);
14088 viewport_set_background(device
, full_viewport
, black_background
);
14090 U1(clear_rect
).x1
= U2(clear_rect
).y1
= 0;
14091 U3(clear_rect
).x2
= rt_sizes
[i
].x
;
14092 U4(clear_rect
).y2
= rt_sizes
[i
].y
;
14094 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
14096 expected_failure
= tests
[j
].vp
.dwX
+ tests
[j
].vp
.dwWidth
> rt_sizes
[i
].x
14097 || tests
[j
].vp
.dwY
+ tests
[j
].vp
.dwHeight
> rt_sizes
[i
].y
;
14099 hr
= IDirect3DViewport2_Clear(full_viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
14100 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x (i %u, j %u).\n", hr
, i
, j
);
14102 hr
= IDirect3D2_CreateViewport(d3d
, &viewport
, NULL
);
14103 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x (i %u, j %u).\n", hr
, i
, j
);
14104 hr
= IDirect3DViewport2_SetViewport2(viewport
, NULL
);
14105 ok(hr
== E_INVALIDARG
, "Setting NULL viewport data returned unexpected hr %#x (i %u, j %u).\n",
14107 memset(&vp
, 0, sizeof(vp
));
14108 vp
.dwSize
= sizeof(vp
);
14109 vp
.dwX
= tests
[j
].vp
.dwX
;
14110 vp
.dwY
= tests
[j
].vp
.dwY
;
14111 vp
.dwWidth
= tests
[j
].vp
.dwWidth
;
14112 vp
.dwHeight
= tests
[j
].vp
.dwHeight
;
14113 vp
.dvScaleX
= tests
[j
].vp
.dwWidth
/ 2.0f
;
14114 vp
.dvScaleY
= tests
[j
].vp
.dwHeight
/ 2.0f
;
14117 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp
);
14118 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
,
14119 "Setting viewport data returned unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
14120 hr
= IDirect3DDevice2_AddViewport(device
, viewport
);
14121 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x (i %u, j %u).\n", hr
, i
, j
);
14122 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp
);
14123 if (expected_failure
)
14124 ok(hr
== E_INVALIDARG
, "Setting viewport data returned unexpected hr %#x (i %u, j %u).\n",
14127 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x (i %u, j %u).\n", hr
, i
, j
);
14129 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
14130 ok(SUCCEEDED(hr
), "Failed to set the viewport, hr %#x (i %u, j %u).\n", hr
, i
, j
);
14131 if (expected_failure
)
14133 destroy_viewport(device
, viewport
);
14137 hr
= IDirect3DDevice2_BeginScene(device
);
14138 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x (i %u, j %u).\n", hr
, i
, j
);
14139 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
14140 ok(SUCCEEDED(hr
), "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
14141 hr
= IDirect3DDevice2_EndScene(device
);
14142 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x (i %u, j %u).\n", hr
, i
, j
);
14144 check_rect(rt
, tests
[j
].expected_rect
, tests
[j
].message
);
14146 destroy_viewport(device
, viewport
);
14149 destroy_viewport(device
, full_viewport
);
14151 hr
= IDirectDrawSurface_DeleteAttachedSurface(rt
, 0, ds
);
14152 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x (i %u).\n", hr
, i
);
14153 IDirectDrawSurface_Release(ds
);
14155 IDirectDrawSurface_Release(rt
);
14158 destroy_material(black_background
);
14159 refcount
= IDirect3DDevice2_Release(device
);
14160 ok(!refcount
, "Device has %u references left.\n", refcount
);
14161 IDirect3D2_Release(d3d
);
14162 IDirectDraw2_Release(ddraw
);
14163 DestroyWindow(window
);
14166 static void test_find_device(void)
14168 D3DFINDDEVICESEARCH search
= {0};
14169 D3DFINDDEVICERESULT result
= {0};
14170 IDirect3DDevice2
*device
;
14171 IDirectDraw2
*ddraw
;
14181 D3DDEVICEDESC_V1 hw_desc
;
14182 D3DDEVICEDESC_V1 sw_desc
;
14189 D3DDEVICEDESC_V2 hw_desc
;
14190 D3DDEVICEDESC_V2 sw_desc
;
14193 static const struct
14200 {&IID_IDirect3D
, DDERR_NOTFOUND
},
14201 {&IID_IDirect3DRampDevice
, D3D_OK
},
14202 {&IID_IDirect3DRGBDevice
, D3D_OK
},
14203 {&IID_IDirect3DMMXDevice
, D3D_OK
},
14204 {&IID_IDirect3DRefDevice
, DDERR_NOTFOUND
},
14205 {&IID_IDirect3DTnLHalDevice
, DDERR_NOTFOUND
},
14206 {&IID_IDirect3DNullDevice
, DDERR_NOTFOUND
},
14209 ddraw
= create_ddraw();
14210 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14212 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
14214 skip("D3D interface is not available, skipping test.\n");
14215 IDirectDraw2_Release(ddraw
);
14219 result
.dwSize
= sizeof(result
);
14220 search
.dwSize
= sizeof(search
);
14221 hr
= IDirect3D2_FindDevice(d3d
, NULL
, NULL
);
14222 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14223 hr
= IDirect3D2_FindDevice(d3d
, NULL
, &result
);
14224 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14225 hr
= IDirect3D2_FindDevice(d3d
, &search
, NULL
);
14226 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14227 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14228 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14229 ok(result
.dwSize
== sizeof(result
), "Got unexpected result size %u.\n", result
.dwSize
);
14230 ok(result
.ddHwDesc
.dwSize
== sizeof(result_v2
.hw_desc
),
14231 "Got unexpected HW desc size %u.\n", result
.ddHwDesc
.dwSize
);
14232 ok(result
.ddSwDesc
.dwSize
== sizeof(result_v2
.sw_desc
),
14233 "Got unexpected SW desc size %u.\n", result
.ddSwDesc
.dwSize
);
14235 memset(&search
, 0, sizeof(search
));
14236 memset(&result
, 0, sizeof(result
));
14237 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14238 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14240 search
.dwSize
= sizeof(search
) + 1;
14241 result
.dwSize
= sizeof(result
) + 1;
14242 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14243 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14245 search
.dwSize
= sizeof(search
);
14247 memset(&result_v1
, 0, sizeof(result_v1
));
14248 result_v1
.size
= sizeof(result_v1
);
14249 hr
= IDirect3D2_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v1
);
14250 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14251 ok(result_v1
.hw_desc
.dwSize
== sizeof(result_v2
.hw_desc
),
14252 "Got unexpected HW desc size %u.\n", result_v1
.hw_desc
.dwSize
);
14253 ok(result_v1
.sw_desc
.dwSize
== sizeof(result_v2
.sw_desc
),
14254 "Got unexpected SW desc size %u.\n", result_v1
.sw_desc
.dwSize
);
14256 memset(&result_v2
, 0, sizeof(result_v2
));
14257 result_v2
.size
= sizeof(result_v2
);
14258 hr
= IDirect3D2_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v2
);
14259 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14260 ok(result_v2
.hw_desc
.dwSize
== sizeof(result_v2
.hw_desc
),
14261 "Got unexpected HW desc size %u.\n", result_v2
.hw_desc
.dwSize
);
14262 ok(result_v2
.sw_desc
.dwSize
== sizeof(result_v2
.sw_desc
),
14263 "Got unexpected SW desc size %u.\n", result_v2
.sw_desc
.dwSize
);
14265 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
14267 memset(&search
, 0, sizeof(search
));
14268 search
.dwSize
= sizeof(search
);
14269 search
.dwFlags
= D3DFDS_GUID
;
14270 search
.guid
= *tests
[i
].guid
;
14272 memset(&result
, 0, sizeof(result
));
14273 result
.dwSize
= sizeof(result
);
14275 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14276 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
14277 ok(result
.dwSize
== sizeof(result
), "Test %u: Got unexpected result size %u.\n", i
, result
.dwSize
);
14280 ok(result
.ddHwDesc
.dwSize
== sizeof(result_v2
.hw_desc
),
14281 "Test %u: Got unexpected HW desc size %u.\n", i
, result
.ddHwDesc
.dwSize
);
14282 ok(result
.ddSwDesc
.dwSize
== sizeof(result_v2
.sw_desc
),
14283 "Test %u: Got unexpected SW desc size %u.\n", i
, result
.ddSwDesc
.dwSize
);
14287 ok(!result
.ddHwDesc
.dwSize
,
14288 "Test %u: Got unexpected HW desc size %u.\n", i
, result
.ddHwDesc
.dwSize
);
14289 ok(!result
.ddSwDesc
.dwSize
,
14290 "Test %u: Got unexpected SW desc size %u.\n", i
, result
.ddSwDesc
.dwSize
);
14294 /* The HAL device can only be enumerated if hardware acceleration is present. */
14295 search
.dwSize
= sizeof(search
);
14296 search
.dwFlags
= D3DFDS_GUID
;
14297 search
.guid
= IID_IDirect3DHALDevice
;
14298 result
.dwSize
= sizeof(result
);
14299 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14301 window
= create_window();
14302 device
= create_device(ddraw
, window
, DDSCL_NORMAL
);
14304 ok(!!device
, "Failed to create a 3D device.\n");
14306 ok(!device
, "Succeeded to create a 3D device.\n");
14308 IDirect3DDevice2_Release(device
);
14309 DestroyWindow(window
);
14311 /* Curiously the colour model criteria seem to be ignored. */
14312 search
.dwSize
= sizeof(search
);
14313 search
.dwFlags
= D3DFDS_COLORMODEL
;
14314 search
.dcmColorModel
= 0xdeadbeef;
14315 result
.dwSize
= sizeof(result
);
14316 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14317 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14319 IDirect3D2_Release(d3d
);
14320 IDirectDraw2_Release(ddraw
);
14323 static IDirectDraw2
*killfocus_ddraw
;
14324 static IDirectDrawSurface
*killfocus_surface
;
14326 static LRESULT CALLBACK
killfocus_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
14330 if (message
== WM_KILLFOCUS
)
14332 ref
= IDirectDrawSurface_Release(killfocus_surface
);
14333 ok(!ref
, "Unexpected surface refcount %u.\n", ref
);
14334 ref
= IDirectDraw2_Release(killfocus_ddraw
);
14335 ok(!ref
, "Unexpected ddraw refcount %u.\n", ref
);
14336 killfocus_ddraw
= NULL
;
14339 return DefWindowProcA(window
, message
, wparam
, lparam
);
14342 static void test_killfocus(void)
14344 DDSURFACEDESC surface_desc
;
14347 WNDCLASSA wc
= {0};
14349 wc
.lpfnWndProc
= killfocus_proc
;
14350 wc
.lpszClassName
= "ddraw_killfocus_wndproc_wc";
14351 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
14353 window
= CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW
,
14354 0, 0, 640, 480, 0, 0, 0, 0);
14356 killfocus_ddraw
= create_ddraw();
14357 ok(!!killfocus_ddraw
, "Failed to create a ddraw object.\n");
14359 hr
= IDirectDraw2_SetCooperativeLevel(killfocus_ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
14360 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
14362 memset(&surface_desc
, 0, sizeof(surface_desc
));
14363 surface_desc
.dwSize
= sizeof(surface_desc
);
14364 surface_desc
.dwFlags
= DDSD_CAPS
;
14365 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
14366 hr
= IDirectDraw2_CreateSurface(killfocus_ddraw
, &surface_desc
, &killfocus_surface
, NULL
);
14367 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14369 SetForegroundWindow(GetDesktopWindow());
14370 ok(!killfocus_ddraw
, "WM_KILLFOCUS was not received.\n");
14372 DestroyWindow(window
);
14373 UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL
));
14376 static void test_gdi_surface(void)
14378 IDirectDrawSurface
*primary
, *backbuffer
, *gdi_surface
;
14379 DDSCAPS caps
= {DDSCAPS_BACKBUFFER
};
14380 DDSURFACEDESC surface_desc
;
14381 IDirectDraw2
*ddraw
;
14386 window
= create_window();
14387 ddraw
= create_ddraw();
14388 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14389 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14390 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14392 /* Retrieving the GDI surface requires a primary surface to exist. */
14393 gdi_surface
= (void *)0xc0dec0de;
14394 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14395 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14396 ok(!gdi_surface
, "Got unexpected surface %p.\n", gdi_surface
);
14398 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
14399 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14401 memset(&surface_desc
, 0, sizeof(surface_desc
));
14402 surface_desc
.dwSize
= sizeof(surface_desc
);
14403 surface_desc
.dwFlags
= DDSD_CAPS
;
14404 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
14405 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
14406 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14408 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14409 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14410 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
14411 IDirectDrawSurface_Release(gdi_surface
);
14413 /* Flipping to the GDI surface requires the primary surface to be
14415 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
14416 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
14418 IDirectDrawSurface_Release(primary
);
14420 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
14421 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14423 memset(&surface_desc
, 0, sizeof(surface_desc
));
14424 surface_desc
.dwSize
= sizeof(surface_desc
);
14425 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
14426 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
14427 U5(surface_desc
).dwBackBufferCount
= 1;
14428 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
14429 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14430 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &caps
, &backbuffer
);
14431 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14432 ok(backbuffer
!= primary
, "Got unexpected backbuffer %p.\n", backbuffer
);
14434 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14435 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14436 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
14437 IDirectDrawSurface_Release(gdi_surface
);
14439 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
14440 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14441 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14442 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14443 ok(gdi_surface
== backbuffer
|| broken(gdi_surface
== primary
),
14444 "Got unexpected surface %p, expected %p.\n", gdi_surface
, backbuffer
);
14445 IDirectDrawSurface_Release(gdi_surface
);
14447 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
14448 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14450 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14451 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14452 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
14453 IDirectDrawSurface_Release(gdi_surface
);
14455 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
14456 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14458 IDirectDrawSurface_Release(backbuffer
);
14459 IDirectDrawSurface_Release(primary
);
14461 refcount
= IDirectDraw2_Release(ddraw
);
14462 ok(!refcount
, "%u references left.\n", refcount
);
14463 DestroyWindow(window
);
14466 static void test_alphatest(void)
14468 #define ALPHATEST_PASSED 0x0000ff00
14469 #define ALPHATEST_FAILED 0x00ff0000
14470 D3DRECT rect_full
= {{0}, {0}, {640}, {480}};
14471 IDirect3DMaterial2
*blue
, *failed
;
14472 IDirect3DViewport2
*viewport
;
14473 IDirect3DDevice2
*device
;
14474 IDirectDrawSurface
*rt
;
14475 IDirectDraw2
*ddraw
;
14483 static const struct
14486 D3DCOLOR color_less
;
14487 D3DCOLOR color_equal
;
14488 D3DCOLOR color_greater
;
14492 {D3DCMP_NEVER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
14493 {D3DCMP_LESS
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
14494 {D3DCMP_EQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
14495 {D3DCMP_LESSEQUAL
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
14496 {D3DCMP_GREATER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
14497 {D3DCMP_NOTEQUAL
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
14498 {D3DCMP_GREATEREQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
14499 {D3DCMP_ALWAYS
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
14501 static D3DLVERTEX quad
[] =
14503 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
14504 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
14505 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
14506 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
14509 window
= create_window();
14510 ddraw
= create_ddraw();
14511 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14512 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
14514 skip("Failed to create a 3D device.\n");
14515 IDirectDraw2_Release(ddraw
);
14516 DestroyWindow(window
);
14519 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
14520 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14522 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
14523 failed
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
14525 viewport
= create_viewport(device
, 0, 0, 640, 480);
14526 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
14527 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14529 viewport_set_background(device
, viewport
, blue
);
14530 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
14531 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14532 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
14533 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14534 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
14535 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14536 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHATESTENABLE
, TRUE
);
14537 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14539 viewport_set_background(device
, viewport
, failed
);
14540 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
14542 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHAFUNC
, test_data
[i
].func
);
14543 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14545 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
14546 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14547 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0x70);
14548 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14549 hr
= IDirect3DDevice2_BeginScene(device
);
14550 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14551 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
14552 D3DVT_LVERTEX
, quad
, ARRAY_SIZE(quad
), 0);
14553 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14554 hr
= IDirect3DDevice2_EndScene(device
);
14555 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14556 color
= get_surface_color(rt
, 320, 240);
14557 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
14558 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
14559 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
14561 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
14562 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14563 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0xff70);
14564 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14565 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, &value
);
14566 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14567 ok(value
== 0xff70, "Got unexpected value %#x.\n", value
);
14568 hr
= IDirect3DDevice2_BeginScene(device
);
14569 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14570 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
14571 D3DVT_LVERTEX
, quad
, ARRAY_SIZE(quad
), 0);
14572 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14573 hr
= IDirect3DDevice2_EndScene(device
);
14574 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14575 color
= get_surface_color(rt
, 320, 240);
14576 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
14577 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
14578 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
14581 destroy_viewport(device
, viewport
);
14582 destroy_material(failed
);
14583 destroy_material(blue
);
14584 IDirectDrawSurface_Release(rt
);
14585 refcount
= IDirect3DDevice2_Release(device
);
14586 ok(!refcount
, "Device has %u references left.\n", refcount
);
14587 refcount
= IDirectDraw2_Release(ddraw
);
14588 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
14589 DestroyWindow(window
);
14592 static void test_clipper_refcount(void)
14594 IDirectDrawSurface
*surface
;
14595 IDirectDrawClipper
*clipper
, *clipper2
;
14596 DDSURFACEDESC surface_desc
;
14597 IDirectDraw2
*ddraw
;
14598 IDirectDraw
*ddraw1
;
14603 const IDirectDrawClipperVtbl
*orig_vtbl
;
14605 window
= create_window();
14606 ddraw
= create_ddraw();
14607 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14608 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14609 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14611 memset(&surface_desc
, 0, sizeof(surface_desc
));
14612 surface_desc
.dwSize
= sizeof(surface_desc
);
14613 surface_desc
.dwFlags
= DDSD_CAPS
;
14614 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
14615 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14616 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14618 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
14619 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
14620 refcount
= get_refcount((IUnknown
*)clipper
);
14621 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
14623 /* Show that clipper validation doesn't somehow happen through per-clipper vtable
14625 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper2
, NULL
);
14626 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
14627 ok(clipper
->lpVtbl
== clipper2
->lpVtbl
, "Got different clipper vtables %p and %p.\n",
14628 clipper
->lpVtbl
, clipper2
->lpVtbl
);
14629 orig_vtbl
= clipper
->lpVtbl
;
14630 IDirectDrawClipper_Release(clipper2
);
14632 /* Surfaces hold a reference to clippers. No surprises there. */
14633 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
14634 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
14635 refcount
= get_refcount((IUnknown
*)clipper
);
14636 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
14638 hr
= IDirectDrawSurface_GetClipper(surface
, &clipper2
);
14639 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#x.\n", hr
);
14640 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
14641 refcount
= IDirectDrawClipper_Release(clipper2
);
14642 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
14644 hr
= IDirectDrawSurface_SetClipper(surface
, NULL
);
14645 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
14646 refcount
= get_refcount((IUnknown
*)clipper
);
14647 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
14649 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
14650 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
14651 refcount
= get_refcount((IUnknown
*)clipper
);
14652 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
14654 refcount
= IDirectDrawSurface_Release(surface
);
14655 ok(!refcount
, "%u references left.\n", refcount
);
14656 refcount
= get_refcount((IUnknown
*)clipper
);
14657 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
14659 /* SetClipper with an invalid pointer crashes. */
14661 /* Clipper methods work with a broken vtable, with the exception of Release. */
14662 clipper
->lpVtbl
= (void *)0xdeadbeef;
14663 refcount
= orig_vtbl
->AddRef(clipper
);
14664 todo_wine
ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
14665 refcount
= orig_vtbl
->Release(clipper
);
14666 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
14668 clipper
->lpVtbl
= orig_vtbl
;
14669 refcount
= orig_vtbl
->Release(clipper
);
14670 todo_wine
ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
14672 /* Fix the refcount difference because Wine did not increase the ref in the
14673 * AddRef call above. */
14676 refcount
= IDirectDrawClipper_Release(clipper
);
14677 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
14680 /* Steal the reference and see what happens - releasing the surface works fine.
14681 * The clipper is destroyed and not kept alive by a hidden refcount - trying to
14682 * release it after the GetClipper call is likely to crash, and certain to crash
14683 * if we allocate and zero as much heap memory as we can get. */
14684 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14685 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14686 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
14687 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
14688 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
14689 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
14691 IDirectDrawClipper_Release(clipper
);
14692 IDirectDrawClipper_Release(clipper
);
14696 /* Disabled because it causes heap corruption (HeapValidate fails and random
14697 * hangs in a later HeapFree) on Windows on one of my Machines: MacbookPro 10,1
14698 * running Windows 10 18363.535 and Nvidia driver 425.31. Driver version 441.66
14699 * is affected too. Some testbot machines have crashes directly in GetClipper
14700 * or proceed with a corrupted heap too.
14702 * The same Windows and driver versions run the test without heap corruption on
14703 * a Geforce 1060 GTX card. I have not seen the problem on AMD GPUs either. */
14704 hr
= IDirectDrawSurface_GetClipper(surface
, &clipper2
);
14705 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#x.\n", hr
);
14706 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
14709 /* Show that invoking the Release method does not crash, but don't get the
14710 * vtable through the clipper pointer because it is no longer pointing to
14712 refcount
= orig_vtbl
->Release(clipper
);
14713 ok(!refcount
, "%u references left.\n", refcount
);
14715 refcount
= IDirectDrawSurface_Release(surface
);
14716 ok(!refcount
, "%u references left.\n", refcount
);
14718 /* It looks like the protection against invalid thispointers is part of
14719 * the IDirectDrawClipper method implementation, not IDirectDrawSurface. */
14720 clipper
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 0x1000);
14721 ok(!!clipper
, "failed to allocate memory\n");
14723 /* Assigning the vtable to our fake clipper does NOT make a difference on
14724 * native - there is a different member of the clipper implementation struct
14725 * that is used to determine if a clipper is valid. */
14726 clipper
->lpVtbl
= orig_vtbl
;
14728 refcount
= orig_vtbl
->AddRef(clipper
);
14729 todo_wine
ok(!refcount
, "Got refcount %u.\n", refcount
);
14730 refcount
= orig_vtbl
->AddRef((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef);
14731 ok(!refcount
, "Got refcount %u.\n", refcount
);
14734 hr
= orig_vtbl
->IsClipListChanged(clipper
, &changed
);
14735 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14736 todo_wine
ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
14739 hr
= orig_vtbl
->IsClipListChanged((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef, &changed
);
14740 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14741 ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
14743 /* Nope, we can't initialize our fake clipper. */
14744 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirectDraw
, (void **)&ddraw1
);
14745 ok(SUCCEEDED(hr
), "Failed to get ddraw1 interface, hr %#x.\n", hr
);
14747 hr
= orig_vtbl
->Initialize(clipper
, ddraw1
, 0);
14748 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14750 IDirectDraw_Release(ddraw1
);
14752 HeapFree(GetProcessHeap(), 0, clipper
);
14754 refcount
= IDirectDraw2_Release(ddraw
);
14755 ok(!refcount
, "%u references left.\n", refcount
);
14756 DestroyWindow(window
);
14759 static void test_caps(void)
14761 DWORD caps_never
, caps_always
, caps_hal
;
14762 DDCAPS hal_caps
, hel_caps
;
14763 IDirectDraw2
*ddraw
;
14764 IDirectDraw
*ddraw1
;
14768 caps_never
= DDSCAPS_RESERVED1
14770 | DDSCAPS_PRIMARYSURFACELEFT
14771 | DDSCAPS_SYSTEMMEMORY
14773 | DDSCAPS_WRITEONLY
14774 | DDSCAPS_LIVEVIDEO
14777 | DDSCAPS_RESERVED2
14780 | DDSCAPS_ALLOCONLOAD
14781 | DDSCAPS_VIDEOPORT
14782 | DDSCAPS_STANDARDVGAMODE
14783 | DDSCAPS_OPTIMIZED
;
14785 caps_always
= DDSCAPS_FLIP
14786 | DDSCAPS_OFFSCREENPLAIN
14787 | DDSCAPS_PRIMARYSURFACE
14792 caps_hal
= DDSCAPS_BACKBUFFER
14794 | DDSCAPS_FRONTBUFFER
14796 | DDSCAPS_VIDEOMEMORY
14797 | DDSCAPS_LOCALVIDMEM
14798 | DDSCAPS_NONLOCALVIDMEM
;
14800 ddraw
= create_ddraw();
14801 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14803 memset(&hal_caps
, 0, sizeof(hal_caps
));
14804 memset(&hel_caps
, 0, sizeof(hel_caps
));
14805 hal_caps
.dwSize
= sizeof(hal_caps
);
14806 hel_caps
.dwSize
= sizeof(hel_caps
);
14807 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
14808 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14809 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
14810 "Got unexpected caps %#x, expected %#x.\n",
14811 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
14812 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
14813 "Got unexpected caps %#x, expected %#x.\n",
14814 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
14816 no3d
= !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
);
14817 if (hal_caps
.ddsCaps
.dwCaps
)
14819 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
14820 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
14821 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
14822 "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
14824 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
14825 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
14826 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
14827 "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
14829 IDirectDraw2_Release(ddraw
);
14831 if (hal_caps
.ddsCaps
.dwCaps
)
14833 hr
= DirectDrawCreate((GUID
*)DDCREATE_HARDWAREONLY
, &ddraw1
, NULL
);
14834 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14835 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw
);
14836 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14837 IDirectDraw_Release(ddraw1
);
14839 memset(&hal_caps
, 0, sizeof(hal_caps
));
14840 memset(&hel_caps
, 0, sizeof(hel_caps
));
14841 hal_caps
.dwSize
= sizeof(hal_caps
);
14842 hel_caps
.dwSize
= sizeof(hel_caps
);
14843 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
14844 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14845 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
14846 "Got unexpected caps %#x, expected %#x.\n",
14847 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
14848 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
14849 "Got unexpected caps %#x, expected %#x.\n",
14850 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
14852 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
14853 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
14854 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
14855 "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
14858 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
14859 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
14860 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
14861 "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
14865 todo_wine
ok(!hel_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
14868 IDirectDraw2_Release(ddraw
);
14871 hr
= DirectDrawCreate((GUID
*)DDCREATE_EMULATIONONLY
, &ddraw1
, NULL
);
14872 ok(hr
== DD_OK
|| (is_ddraw64
&& hr
== E_FAIL
), "Got unexpected hr %#x.\n", hr
);
14875 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw
);
14876 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14877 IDirectDraw_Release(ddraw1
);
14879 memset(&hal_caps
, 0, sizeof(hal_caps
));
14880 memset(&hel_caps
, 0, sizeof(hel_caps
));
14881 hal_caps
.dwSize
= sizeof(hal_caps
);
14882 hel_caps
.dwSize
= sizeof(hel_caps
);
14883 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
14884 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14885 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
14886 "Got unexpected caps %#x, expected %#x.\n",
14887 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
14888 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
14889 "Got unexpected caps %#x, expected %#x.\n",
14890 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
14892 todo_wine
ok(!hal_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
14893 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
14894 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
14895 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
14896 "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
14898 IDirectDraw2_Release(ddraw
);
14902 static void test_d32_support(void)
14904 IDirectDrawSurface
*surface
;
14905 DDSURFACEDESC surface_desc
;
14906 IDirectDraw2
*ddraw
;
14911 window
= create_window();
14912 ddraw
= create_ddraw();
14913 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14914 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14915 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14917 memset(&surface_desc
, 0, sizeof(surface_desc
));
14918 surface_desc
.dwSize
= sizeof(surface_desc
);
14919 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
14920 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
14921 U2(surface_desc
).dwZBufferBitDepth
= 32;
14922 surface_desc
.dwWidth
= 64;
14923 surface_desc
.dwHeight
= 64;
14924 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14925 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14927 memset(&surface_desc
, 0, sizeof(surface_desc
));
14928 surface_desc
.dwSize
= sizeof(surface_desc
);
14929 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
14930 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14931 ok((surface_desc
.dwFlags
& DDSD_ZBUFFERBITDEPTH
), "Got unexpected flags %#x.\n", surface_desc
.dwFlags
);
14932 ok(U2(surface_desc
).dwZBufferBitDepth
== 32,
14933 "Got unexpected dwZBufferBitDepth %u.\n", U2(surface_desc
).dwZBufferBitDepth
);
14934 ok(!(surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
),
14935 "Got unexpected surface caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
14936 IDirectDrawSurface_Release(surface
);
14938 refcount
= IDirectDraw2_Release(ddraw
);
14939 ok(!refcount
, "%u references left.\n", refcount
);
14940 DestroyWindow(window
);
14943 struct find_different_mode_param
14945 unsigned int old_width
;
14946 unsigned int old_height
;
14947 unsigned int old_frequency
;
14948 unsigned int new_width
;
14949 unsigned int new_height
;
14950 unsigned int new_frequency
;
14951 unsigned int new_bpp
;
14954 static HRESULT CALLBACK
find_different_mode_callback(DDSURFACEDESC
*surface_desc
, void *context
)
14956 struct find_different_mode_param
*param
= context
;
14958 if (U1(U4(*surface_desc
).ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
14959 return DDENUMRET_OK
;
14961 if (surface_desc
->dwWidth
!= param
->old_width
&& surface_desc
->dwHeight
!= param
->old_height
&&
14962 surface_desc
->dwRefreshRate
!= param
->old_frequency
)
14964 param
->new_width
= surface_desc
->dwWidth
;
14965 param
->new_height
= surface_desc
->dwHeight
;
14966 param
->new_frequency
= surface_desc
->dwRefreshRate
;
14967 param
->new_bpp
= surface_desc
->ddpfPixelFormat
.dwRGBBitCount
;
14968 return DDENUMRET_CANCEL
;
14971 return DDENUMRET_OK
;
14974 static void test_cursor_clipping(void)
14976 struct find_different_mode_param param
;
14977 DDSURFACEDESC surface_desc
;
14978 RECT rect
, clip_rect
;
14979 IDirectDraw2
*ddraw
;
14984 window
= create_window();
14985 ok(!!window
, "Failed to create a window.\n");
14986 ddraw
= create_ddraw();
14987 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14989 memset(&surface_desc
, 0, sizeof(surface_desc
));
14990 surface_desc
.dwSize
= sizeof(surface_desc
);
14991 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
14992 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#x.\n", hr
);
14994 memset(¶m
, 0, sizeof(param
));
14995 param
.old_width
= surface_desc
.dwWidth
;
14996 param
.old_height
= surface_desc
.dwHeight
;
14997 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, find_different_mode_callback
);
14998 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#x.\n", hr
);
14999 if (!(param
.new_width
&& param
.new_height
))
15001 skip("Failed to find a different mode than %ux%u.\n", param
.old_width
, param
.old_height
);
15005 ret
= ClipCursor(NULL
);
15006 ok(ret
, "ClipCursor failed, error %#x.\n", GetLastError());
15007 get_virtual_rect(&rect
);
15008 ret
= GetClipCursor(&clip_rect
);
15009 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
15010 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15011 wine_dbgstr_rect(&clip_rect
));
15013 /* Set cooperative level to normal */
15014 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15015 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
15017 get_virtual_rect(&rect
);
15018 ret
= GetClipCursor(&clip_rect
);
15019 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
15020 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15021 wine_dbgstr_rect(&clip_rect
));
15023 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
15024 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#x.\n", hr
);
15027 win_skip("SetDisplayMode failed, hr %#x.\n", hr
);
15031 get_virtual_rect(&rect
);
15032 ret
= GetClipCursor(&clip_rect
);
15033 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
15034 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15035 wine_dbgstr_rect(&clip_rect
));
15037 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
15038 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
15040 get_virtual_rect(&rect
);
15041 ret
= GetClipCursor(&clip_rect
);
15042 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
15043 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15044 wine_dbgstr_rect(&clip_rect
));
15046 /* Switch to full screen cooperative level */
15047 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
15048 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
15050 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
15051 ret
= GetClipCursor(&clip_rect
);
15052 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
15053 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15054 wine_dbgstr_rect(&clip_rect
));
15056 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
15057 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#x.\n", hr
);
15060 win_skip("SetDisplayMode failed, hr %#x.\n", hr
);
15064 SetRect(&rect
, 0, 0, param
.new_width
, param
.new_height
);
15065 ret
= GetClipCursor(&clip_rect
);
15066 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
15067 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15068 wine_dbgstr_rect(&clip_rect
));
15070 /* Restore display mode */
15071 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
15072 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
15074 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
15075 ret
= GetClipCursor(&clip_rect
);
15076 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
15077 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15078 wine_dbgstr_rect(&clip_rect
));
15080 /* Switch to normal cooperative level */
15081 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15082 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
15084 get_virtual_rect(&rect
);
15085 ret
= GetClipCursor(&clip_rect
);
15086 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
15087 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15088 wine_dbgstr_rect(&clip_rect
));
15091 IDirectDraw2_Release(ddraw
);
15092 DestroyWindow(window
);
15095 static BOOL CALLBACK
test_window_position_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
15098 RECT primary_rect
, window_rect
;
15099 IDirectDraw2
*ddraw
;
15104 ddraw
= create_ddraw();
15105 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15106 window
= CreateWindowA("static", "ddraw_test", WS_POPUP
| WS_VISIBLE
, monitor_rect
->left
,
15107 monitor_rect
->top
, monitor_rect
->right
- monitor_rect
->left
,
15108 monitor_rect
->bottom
- monitor_rect
->top
, NULL
, NULL
, NULL
, NULL
);
15109 ok(!!window
, "Failed to create a window.\n");
15112 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
15113 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
15115 ret
= GetWindowRect(window
, &window_rect
);
15116 ok(ret
, "GetWindowRect failed, error %#x.\n", GetLastError());
15117 SetRect(&primary_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
15118 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
15119 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
15121 /* Window activation should restore the window to fit the whole primary monitor */
15122 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
15123 SWP_NOZORDER
| SWP_NOSIZE
);
15124 ok(ret
, "SetWindowPos failed, error %#x.\n", GetLastError());
15125 ret
= SetForegroundWindow(GetDesktopWindow());
15126 ok(ret
, "Failed to set foreground window.\n");
15128 ret
= ShowWindow(window
, SW_RESTORE
);
15129 ok(ret
, "Failed to restore window, error %#x.\n", GetLastError());
15131 ret
= SetForegroundWindow(window
);
15132 ok(ret
, "SetForegroundWindow failed, error %#x.\n", GetLastError());
15134 ret
= GetWindowRect(window
, &window_rect
);
15135 ok(ret
, "GetWindowRect failed, error %#x.\n", GetLastError());
15136 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
15137 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
15139 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15140 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
15141 ret
= GetWindowRect(window
, &window_rect
);
15142 ok(ret
, "GetWindowRect failed, error %#x.\n", GetLastError());
15143 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
15144 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
15146 DestroyWindow(window
);
15147 IDirectDraw2_Release(ddraw
);
15151 static void test_window_position(void)
15153 EnumDisplayMonitors(NULL
, NULL
, test_window_position_cb
, 0);
15156 static BOOL CALLBACK
test_get_display_mode_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
15159 DDSURFACEDESC surface_desc
;
15160 IDirectDraw2
*ddraw
;
15165 ddraw
= create_ddraw();
15166 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15167 window
= create_window();
15168 ok(!!window
, "Failed to create a window.\n");
15170 /* Test that DirectDraw doesn't use the device window to determine which monitor to use */
15171 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
15172 SWP_NOZORDER
| SWP_NOSIZE
);
15173 ok(ret
, "SetWindowPos failed, error %#x.\n", GetLastError());
15175 surface_desc
.dwSize
= sizeof(surface_desc
);
15176 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
15177 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#x.\n", hr
);
15178 ok(surface_desc
.dwWidth
== GetSystemMetrics(SM_CXSCREEN
), "Expect width %d, got %d.\n",
15179 GetSystemMetrics(SM_CXSCREEN
), surface_desc
.dwWidth
);
15180 ok(surface_desc
.dwHeight
== GetSystemMetrics(SM_CYSCREEN
), "Expect height %d, got %d.\n",
15181 GetSystemMetrics(SM_CYSCREEN
), surface_desc
.dwHeight
);
15183 DestroyWindow(window
);
15184 IDirectDraw2_Release(ddraw
);
15188 static void test_get_display_mode(void)
15190 static const DWORD flags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_REFRESHRATE
| DDSD_PIXELFORMAT
| DDSD_PITCH
;
15191 struct find_different_mode_param param
;
15192 DDSURFACEDESC surface_desc
;
15193 IDirectDraw2
*ddraw
;
15199 EnumDisplayMonitors(NULL
, NULL
, test_get_display_mode_cb
, 0);
15201 ddraw
= create_ddraw();
15202 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15203 window
= create_window();
15204 ok(!!window
, "Failed to create a window.\n");
15206 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
15207 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
15209 memset(&devmode
, 0, sizeof(devmode
));
15210 devmode
.dmSize
= sizeof(devmode
);
15211 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
15212 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
15214 surface_desc
.dwSize
= sizeof(surface_desc
);
15215 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
15216 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#x.\n", hr
);
15217 ok(surface_desc
.dwSize
== sizeof(surface_desc
), "Expected dwSize %u, got %u.\n",
15218 sizeof(surface_desc
), surface_desc
.dwSize
);
15219 ok(surface_desc
.dwFlags
== flags
, "Expected dwFlags %#x, got %#x.\n", flags
,
15220 surface_desc
.dwFlags
);
15221 ok(surface_desc
.dwWidth
== devmode
.dmPelsWidth
, "Expected width %u, got %u.\n",
15222 devmode
.dmPelsWidth
, surface_desc
.dwWidth
);
15223 ok(surface_desc
.dwHeight
== devmode
.dmPelsHeight
, "Expected height %u, got %u.\n",
15224 devmode
.dmPelsHeight
, surface_desc
.dwHeight
);
15225 ok(surface_desc
.dwRefreshRate
== devmode
.dmDisplayFrequency
, "Expected frequency %u, got %u.\n",
15226 devmode
.dmDisplayFrequency
, surface_desc
.dwRefreshRate
);
15227 ok(surface_desc
.ddpfPixelFormat
.dwSize
== sizeof(surface_desc
.ddpfPixelFormat
),
15228 "Expected ddpfPixelFormat.dwSize %u, got %u.\n", sizeof(surface_desc
.ddpfPixelFormat
),
15229 surface_desc
.ddpfPixelFormat
.dwSize
);
15230 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== devmode
.dmBitsPerPel
,
15231 "Expected ddpfPixelFormat.dwRGBBitCount %u, got %u.\n", devmode
.dmBitsPerPel
,
15232 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
15233 ok(surface_desc
.lPitch
== devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
15234 "Expected pitch %u, got %u.\n", devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
15235 surface_desc
.lPitch
);
15237 memset(¶m
, 0, sizeof(param
));
15238 param
.old_frequency
= surface_desc
.dwRefreshRate
;
15239 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, DDEDM_REFRESHRATES
, NULL
, ¶m
,
15240 find_different_mode_callback
);
15241 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#x.\n", hr
);
15242 if (!param
.new_frequency
)
15244 skip("Failed to find a display mode with a different frequency.\n");
15248 hr
= IDirectDraw2_SetDisplayMode(ddraw
, param
.new_width
, param
.new_height
, param
.new_bpp
,
15249 param
.new_frequency
, 0);
15250 ok(hr
== DD_OK
, "SetDisplayMode failed, hr %#x.\n", hr
);
15251 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
15252 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#x.\n", hr
);
15253 ok(surface_desc
.dwWidth
== param
.new_width
, "Expected width %u, got %u.\n", param
.new_width
,
15254 surface_desc
.dwWidth
);
15255 ok(surface_desc
.dwHeight
== param
.new_height
, "Expected height %u, got %u.\n", param
.new_height
,
15256 surface_desc
.dwHeight
);
15257 ok(surface_desc
.dwRefreshRate
== param
.new_frequency
, "Expected frequency %u, got %u.\n",
15258 param
.new_frequency
, surface_desc
.dwRefreshRate
);
15259 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== param
.new_bpp
,
15260 "Expected ddpfPixelFormat.dwRGBBitCount %u, got %u.\n", devmode
.dmBitsPerPel
,
15261 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
15264 DestroyWindow(window
);
15265 IDirectDraw2_Release(ddraw
);
15268 static void run_for_each_device_type(void (*test_func
)(const GUID
*))
15270 test_func(&IID_IDirect3DHALDevice
);
15271 test_func(&IID_IDirect3DRGBDevice
);
15276 DDDEVICEIDENTIFIER identifier
;
15277 DEVMODEW current_mode
;
15278 IDirectDraw2
*ddraw
;
15281 if (!(ddraw
= create_ddraw()))
15283 skip("Failed to create a ddraw object, skipping tests.\n");
15287 if (ddraw_get_identifier(ddraw
, &identifier
))
15289 trace("Driver string: \"%s\"\n", identifier
.szDriver
);
15290 trace("Description string: \"%s\"\n", identifier
.szDescription
);
15291 trace("Driver version %d.%d.%d.%d\n",
15292 HIWORD(U(identifier
.liDriverVersion
).HighPart
), LOWORD(U(identifier
.liDriverVersion
).HighPart
),
15293 HIWORD(U(identifier
.liDriverVersion
).LowPart
), LOWORD(U(identifier
.liDriverVersion
).LowPart
));
15295 IDirectDraw2_Release(ddraw
);
15297 memset(¤t_mode
, 0, sizeof(current_mode
));
15298 current_mode
.dmSize
= sizeof(current_mode
);
15299 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
15300 registry_mode
.dmSize
= sizeof(registry_mode
);
15301 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
15302 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
15303 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
15305 skip("Current mode does not match registry mode, skipping test.\n");
15309 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
15310 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
15312 test_coop_level_create_device_window();
15313 test_clipper_blt();
15314 test_coop_level_d3d_state();
15315 test_surface_interface_mismatch();
15316 test_coop_level_threaded();
15317 run_for_each_device_type(test_depth_blit
);
15318 test_texture_load_ckey();
15319 test_viewport_object();
15327 test_window_style();
15328 test_redundant_mode_set();
15329 test_coop_level_mode_set();
15330 test_coop_level_mode_set_multi();
15332 test_coop_level_surf_create();
15333 test_coop_level_multi_window();
15334 test_clear_rect_count();
15335 test_coop_level_versions();
15336 test_lighting_interface_versions();
15337 test_coop_level_activateapp();
15338 test_unsupported_formats();
15339 run_for_each_device_type(test_rt_caps
);
15340 test_primary_caps();
15341 test_surface_lock();
15342 test_surface_discard();
15344 test_set_surface_desc();
15345 test_user_memory_getdc();
15346 test_sysmem_overlay();
15347 test_primary_palette();
15348 test_surface_attachment();
15349 test_pixel_format();
15350 test_create_surface_pitch();
15352 test_palette_complex();
15356 test_specular_lighting();
15357 test_palette_gdi();
15358 test_palette_alpha();
15359 test_lost_device();
15360 test_surface_desc_lock();
15361 test_texturemapblend();
15362 test_viewport_clear_rect();
15364 test_colorkey_precision();
15365 test_range_colorkey();
15367 test_lockrect_invalid();
15368 test_yv12_overlay();
15369 test_offscreen_overlay();
15370 test_overlay_rect();
15372 test_blt_z_alpha();
15373 test_cross_device_blt();
15375 test_draw_primitive();
15376 test_edge_antialiasing_blending();
15377 test_transform_vertices();
15378 test_display_mode_surface_pixel_format();
15379 test_surface_desc_size();
15380 test_ck_operation();
15381 test_set_render_state();
15382 test_depth_readback();
15384 test_enum_surfaces();
15386 test_find_device();
15388 test_gdi_surface();
15390 test_clipper_refcount();
15392 test_d32_support();
15393 test_cursor_clipping();
15394 test_window_position();
15395 test_get_display_mode();